> For the complete documentation index, see [llms.txt](https://rocape.gitbook.io/xmllanguage/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://rocape.gitbook.io/xmllanguage/chapter1/22xml-wen-dang-de-ji-ben-gou-cheng-yuan-su/221xml-sheng-ming-xmldeclaration.md).

# 2.2.1 XML 声明（ XML Declaration ）

\####2.2.1 XML声明（XML Declaration）

* XML文档的第一行内容，通常是XML的声明部分，说明文档是XML 类型，比如：

```
<?xml version="1.0" encoding="UTF-16" standalone="yes"?>
```

* XML声明部分本身是可选的，但是如果包含声明部分，必须是整个XML文档的第一行内容。
* XML声明以“”结束。
* 完整的XML声明包括三个属性：版本声明（version）、编码声明（encoding）和文档独立性声明（standalone），\*\* 顺序不变 \*\*。

\####XML声明（XML Declaration）

* XML声明必须放在文档的开头，即文档的第一个字符必须是“<”，前面不能有空行或空格。
* 解析器（Parser）不一定严格

\####版本声明

* 在XML的声明中，这个属性是必须的，并且必须作为第一个属性出现。
* version属性的取值用于描述当前XML的版本编号，目前为1.0或1.1，这是为了将来的新版本能够保持向后的兼容性而设计的，一般都应该包含版本编号的声明。

\####编码声明

* UTF-8, UTF-16, GB-2312, ISO-10646-UCS-2, ISO-10646-UCS-4, ISO-8859-1等等都是合法的encoding属性的取值。通常情况下，建议使用UTF-8编码方式，因为这样既可以表示西文字符又可以表示非西文的字符（包括中文）。
* XML规定所有的XML处理器必须内置Unicode。
* encoding属性是**可选**的。
* encoding告诉解析器文档的编码方式，然后解析器按照正确的编码方法读取文档，并转换为Unicode字符。
* 文档没有说明编码，则使用默认的UTF-8或UTF-16 。
* 文档没有说明编码而使用非UTF-8或UTF-16字符，则会引起解析器错误。

\####ASCII字符集

* 在早期字符集中，使用最为频繁的是ASCII的7位字符集，它是由美国信息交换标准委员会为美国英语符号和文字所设计的字符集。
* 在EASCII中，原前0-127的符号保持不变，而值为128-255之间的字符则用于表格符号、计算符号、希腊字母和特殊的拉丁符号。
* EASCII实际上等同于国际标准化组织的标准ISO 8859-1，简称为ISO Latin-1。ISO Latin-1是现今最通用的、最常见的单字节编码系统。

\####Unicode的出现

* 单个字节编码系统可以表示28=256个不同的符号和文字，但需要在计算机中表示的、或者需要使用计算机来进行处理的符号和文字越来越多，256种编码是远远不够的。
* Unicode 1.0 (ISO/IEC 10646)通过增加一个高字节对ISO Latin-1字符集进行扩展。

\####UTF-8编码实现方式

* UTF-8采用变长（1-3个字节）的方式来表示65536以内的基本字符。UTF-8非常适合于进行数据传输 ![](https://3059093206-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fab03SpGiz5z7LDfmckYx%2Fuploads%2Fgit-blob-86b1f77e4a49cd51e719e024be76ee4c62fe4853%2F2.3.bmp?alt=media) ####XML和Unicode及其他字符集
* XML支持Unicode。 `<title>&#x5B66;&#x4E60;&#x58;&#x4D;&#x4C;</title>` 将被解析为？？？
* 在符合XML规范的编辑器中，可以直接使用中文作为元素的名称（Han Ideographs for Element Names）。<标题>学习XML\</标题>
* 但是所使用的汉字必须是ISO 10646中的“统一汉字（Uni-Han）”。
* encoding属性的取值与XML文档保存时采用的编码格式没有直接的关系。

\####Base64 编码表 ![](https://3059093206-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fab03SpGiz5z7LDfmckYx%2Fuploads%2Fgit-blob-5ebbb19a722f93f72a9bad3d78690b284fe06f05%2F2.4.bmp?alt=media) ####Base64 编码方式

* 把每三个8Bit的字节转换为四个6Bit的字节（3*8 = 4*6 = 24），然后把6Bit再添两位高位0，组成四个8Bit的字节。
* 比如00001010 11001010 01101100将分解为000010 101100 101001 101100，每6Bit高位补0，然后查表，将转换为C、s、p、s。

\####文档独立性声明

* standalone属性（The Standalone Document Declaration, SDD）是**可选**的，其取值表明当前XML文档是独立使用还是与其他的标记文件配套使用。
* yes：表示在解析当前XML文档时，无需其他的外部标记声明文件。
* no：表示在解析当前文档时可能需要使用外部的标记声明文件（DTD）。

\####标签、文本和元素

* 区分XML文档信息与标签
* 处在“<”和“>”之间的是XML标签（Tag），处在标签之间的文本是文档信息或数据，文档中的全部标签组成了XML的标记语言。
* 标签成对出现，每一个开始标签都有一个结束标签与之对应（和）
* 开始标签到结束标签之间的文本以及标签本身统称为元素（Element）
* John
* 在XML文档中，元素是最基本的组成单元（Building Block）。
* XML元素指的是从（且包括）开始标签直到（且包括）结束标签的部分。元素中可以包含文本、子元素或两者混合。元素也可以有属性。
* 元素的语法格式如下所示：\
  \<element\_name att1=“val1” att2=“val2”> ――开始标签\
  ...content... ――元素内容（文本、子元素或两者混合）\
  \</element\_name> ――结束标签 标签、文本和元素
* 元素的开始标签与结束标签之间的文本称为元素内容。
* 标签之间的元素内容经常就是数据（与其他元素相对应）。
* 元素的内容称为可解析的字符数据（Parsed Character Data, PCDATA）。
* 文本内容或文本节点
* 标签结束符“>”之前可插入空格或回车，在标签开始符“<”和/之后紧跟标签名。

\####根元素（Root Element）

* 整个文档也是一个元素，称为根元素，把其他元素包含在内。
* 根元素是文档的顶层元素，其他元素都是其子元素，**一个XML文档必须有且只有一个根元素**。
* 即使XML文档没有任何内容，也必须有一个根元素。
* 如果某个XML文档有多个根元素，只需增加一个更高层的元素让其包含原有的根元素。

\####元素名的命名规则

* 在定义元素时，其命名必须遵循下面的规则：
* 元素的名称必须以字母、或者下划线（\_）开头，尽量不用“xml”的任意大小写形式开始 。
* 元素名称中除首个符号之外的部分可以是字母、数字、横线（-）、下划线（\_）、点号（.）的任意组合，不能有空格。
* 冒号（:）是保留的，可在命名空间中使用。
* 元素名称是大小写敏感的，因此开始标记和结束标记中元素名称的大小写形式必须完全相同。
* 元素名称长度没有限制。
* 可以使用非英文的元素名。

\####有关元素命名的示例

* 下列XML 标记名称都是正确的： `<example-one>、<_example2>、<Example.Three>`
* 下列XML 标记名称都是错误的： `<bad*charater>、<illegal space>、<12number-start>`

\####空元素（Empty Element）

* 在XML文档中，元素的内容可以为空，比如，这表示该元素中不包含任何内容。
* 空元素还有另外一种书写形式，即

  ，**/与>必须在一起**，这个标记既是开始标记又是结束标记。上面两种写法是完全等价的。
* 空元素是指不包含任何内容的元素，但是在其开始标记中可以包含属性，比如： `<details about="Location"></details>`

\####属性（Attribute）

* 属性不能独立于元素而存在，通常以名-值对的形式出现，属性的取值必须加上引号（单引号或者双引号）。
* 属性的名-值对用于描述当前元素的某个方面的特征，比如： `<authorfirstname="tom"lastname="hanks"></ author>`
* 元素的命名规则同样适用于属性的命名。
* 属性都必须有一个值，即使其值为空字符串（””）

\####元素VS.属性

* 元素内容中的子元素和属性，都可以用来刻画该元素某个方面的特征。

```
<book>
    <author>
        <firstname>tom</firstname>
        <lastname>hanks</lastname>
    </author>
    ......
</book>
```

请输入代码\
Test \* 那么在实际使用时，应该选择哪一种方式呢？

* 对于简单的标量数据（无结构的数据），可以采用属性，否则应该采用子元素。
* 对于可能在数目上发生变化的特性，应该使用子元素，比如某本书籍可能有多个作者：

```xml
<book>
    <author>tom hanks</author>
    <author>mike jimmy</author>
    ......
</book>
```

请输入代码\
Test

* 这种方法修改了元数据的内容，即属性名称本身，可能会影响到已经编写的用于解析该文档的应用程序。所以，使用子元素的方案在可扩展性方面更好。 `<book author1="tom hanks"author2="mike jimmy">...</book>` ####有关XML文档中的元素的补充说明
* 一个元素可以包含任意多个子元素，可以包含多个同名的子元素。nn元素之间不存在对称关系。
* 子元素的顺序是非常重要的，比如在前面的例子中，第一个author元素可能表示该书籍的第一作者，而第二个author元素表示第二作者，所以颠倒顺序后含义完全不同。

\####有关XML文档中的属性的补充说明

* 元素在其开始标记中可以包含任意多个属性，但**不能包含同名的属性**。
* 对于一个元素所有的属性，它们不分先后顺序，因为它们之间可以通过名称相互区别。
* 充分认识和理解元素和属性之间的区别，这对于学习后面的内容是非常重要的。

\####元素的文本内容

* 元素开始标记和结束标记之间的数据称为该元素的内容，而元素可以包含子元素、文本或者两者的混合作为其内容。
* 文本内容也是XML文档中一种非常重要的信息表现形式。比如： `<author>tom hanks</author>`
* 对于计算机程序（比如XML解析器）来说，如何能够确定文本内容和元素标记之间的边界呢？
* 根据元素的语法，我们知道，< >之间的文本是元素的标记，换句话说，<和>符号在XML语法中具有特殊的含义。
* 如果文本内容中出现了<号，比如 `<lessthan>one<two</lessthan>` ？？？
* 关键在于，<可能会产生歧义（究竟是小于号本身、还是XML标记的开始符号），所以<号不能直接在文本内容中出现。

\####文本内容中不应该出现的特殊字符

* XML 1.0 规范中定义了五种预定义实体：

| 字符 | 预定义实体  |
| -- | ------ |
| <  | <      |
| >  | \&gt   |
| &  | \&amp  |
| '  | \&apos |
| "  | "      |

`<lessthan>one<two</lessthan>`（解析之后将会还原）

* 而除此以外的的其他实体，必须在使用前进行声明。

\####CDATA (Character Data)

* 预定义实体为某些非法字符（<和&）提供了相应的替代使用方式，但使用起来不太方便，同时会降低原始XML文档的可读性。
* XML1.0规范为此提供了另一种解决方案，即CDATA段。
* 假设XML文档的某块文本内容中包含大量的特殊字符，那么可以将整个文本块的内容放入到一个CDATA段中（）。
* 使用CDATA段，可以告诉解析器不要试图从该文本块中查找XML标记，它仅仅就是文本内容，从而避免了歧义的产生，因此可以使用非法字符。 `<comparison><![CDATA[6 is < 7 & 7 > 6]]></comparison>`
* 同理，CDATA段的文本内容中不能直接出现]]>，并且CDATA段不应该嵌套使用。如果需要]]>，使用\*\*]]>\*\*

\####空白字符（White Space）

* XML 1.0规范明确指出，XML文档中的空白字符包括空格、回车、换行、制表等四种符号。
* 在缺省的情况下，对于连续出现的空白字符，解析器会将其缩减为一个空格字符。
* Windows行结束符用换行符和回车符两个字符，UNIX只用换行符，为提高互操作性，XML解析器在处理之前把所有的行结束符转换为单个换行符。

\####XML文档的良构性规则

* 通常将语法形式上正确的XML文档称为良构的（Well-formed）XML文档，这是对XML文档的最基本的要求，其目的是确保能够将文档转换为树型结构，从而使用计算机程序对其进行正确地解析。
* 良构的XML文档必须满足的下面五个要求。XML文档的良构性规则

1. 开始标记必须与结束标记相对应； `<book><author>tom hanks</author></book>` 是正确的 `<book><author>tom hanks</book>` 是错误的
2. 标记是大小写敏感的； `<book>...</book>` 是正确的 `<book>...</Book>`是错误的
3. 标记必须正确地嵌套； `<book><author>tom hanks</book></author>` 是错误的
4. 属性值必须使用引号扩起来； `<details about=Location />` 是错误的
5. 有且只有一个根元素。这段内容称为XML片段。 `<author>tom hanks</author> <author>mike jimmy</author>` 是错误的

\####注释（Comment）

* 作为标记语言的一种，XML使用了HTML相同的注释语法，即：`<!-- ........ -->`。
* 注释中不应该出现两个连续的横线（-），因为这是标记注释的特殊符号。

```
<!-- John lost his middle name --in a fire -->
<middle></middle <!-- John lost his middle name in a fire -->>
```

* 注释不应该出现在元素的标签中，注释之中不应该嵌套注释。
* 注释只是给阅读XML带来便利，解析器不传递给应用程序。

\####处理指令（Processing Instruction）

* 有时需要在XML文档中嵌入应用程序专用指令，控制文档的处理过程，XML通过PI机制实现其功能。
* 插入的指令不属于文档数据，但会传送给应用程序。 ![](https://3059093206-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fab03SpGiz5z7LDfmckYx%2Fuploads%2Fgit-blob-56e59928e77c89351ae054812df092af71fb2533%2F2.5.bmp?alt=media)
* 在都是希望执行的指令。
* PITarget遵从与元素和属性一样的命名规则
* PITarget: nameprocessor
* PI: PRINT nickname
* 处理指令要谨慎使用
* 可以使用在HTML中只能在注释里的信息，将其传递给应用程序
* **XML声明语句不是一个处理指令**，可能存在两种错误情况
* 试图从XML解析器获取XML声明语句的内容
* 在XML文档的其他地方插入声明语句

\####XML中的错误

* **一般性错误**仅违反规范中的规则，但其结果不能确定，允许XML处理器从这类错误中恢复正常，并继续处理其他内容。
* **致命性错误**比一般性错误严重，当解析器遇到一个致命性错误时，就不能继续正常运行（可能继续处理XML文档，进一步找出文档中的其他错误）。任何导致XML文档不能成为一个良构文档的错误都是致命的错误。
* 严格按照XML语法编写一个XML文档，可以立刻发现文档中的错误并改正过来。
