《XML入门经典》学习进程之第2章良构的XML文档
XML解析器帮助应用程序解析XML文档,并为应用程序提供它所需要的信息。XML解析器读取XML文档中的每个字符,并判断哪些字符是文档的标签,哪些才是数据,并在应用程序处理这些数据之前对XML进行一些其他的必要的处理。
XML文档中的全部标签组成了XML的标记语言。
XML的标签用法与HTML的相同。
首末标签和标签之间的文本内容统称为元素。
标签之间的文本称为元素内容,该概念有专门的术语,即可解析的字符数据(PCDATA)。这些术语都是XML从SGML那里继承过来的。
标签的写法除了传统的<XXX></XXX>之外,还可以写成<XXX/>。这是一种自封闭标签。
XML和HTML定义元素的规则:
- HTML中不一定要像XML一样有了开始标签就得有结束标签。
- HTML中不一定要像XML区分大小写(标签)。
上面这两个区别使HTML的解析器非常难以编写,为了考虑这些因素开发人员必须增加代码,这样会使解析器变得越来越大,随之而来的就是调试的困难上升。
不同的浏览器采用不同的解析方法,所以非标准化的解析方法会造成它们之间的不兼容。
元素的命名规则:
- 首字母必须是英文字母或连字符。
- 名字里不能有空格。
- 不能有冒号。
- 名字的开始字符不可以是xml,不管大写还是小写。
- 元素名和结束符>之间可以有空格,但与<之间不能有。
关于PCDATA里的空白符:
HTML对元素内容中的一个以上的连续的空白符都会进行删除,显示时只留下一个。如要按原文档显示,则需加入某些特殊的HTML标记。而XML则会默认保留这些空白符。
不过,如果用IE浏览器显示XML文档的话,则XML中的空白符仍会像显示HTML一样被删除。这是因为IE并不是直接显示XML文档,它利用XSL将XML转换成HTML,然后再显示。
额外的空白符:
XML中的空白符除了会存在于元素内容中外,还会存在于开始标签之后的行结束符以及开始标签前面的空白符。这些空白符只是使文档更具可读性,它们并不是数据的一部分。
在很多情况下,应用程序根本不须要考虑是否存在空格符,应用程序只须向解析器要求包含在指定歹毒中的数据,根本不会在额外的标签中查询PCDATA。
属性:
元素的名字中是不能包含空格的,这是为了给元素添加属性留下选择的余地。属性只能插入到开始标签而不是结束标签,而且每一个属性都必须有一个值,并用“”或‘’括起来。不过因为在属性值中也可以使用引号,所以在添加引号时不要让解析器误会(比如,“XX‘XX”或’XXX“XX‘都可以,但”XX“XX”就不行了)。
元素名的命名规则与属性名的命名规则相同。另外,同一个元素里的不能有相同的属性名。
同一个元素里的属性顺序并没有要求,但解析器会按元素在文档里的顺序处理元素。
XML解析器在把属性传递给应用程序之前,会将它们进行预处理。其中最重要的就是删除行结束符并用一个空格替代。
在实际中,并不存在真正的元数据——对于应用程序来说,全部信息都是数据。在HTML中,信息分为两大类:一类是给人看的数据,另一类是浏览器用来格式化前一类数据时要用到的数据。我们可以把后一类的数据称为元数据,但对于浏览器或者开发人员来说,元数据也是数据。
属性占用很少的空间,但现在的压缩技术远比为了减小空间而使用大量的属性的方法有更好的效果,而不必多此一举地使用属性。另外,大量使用属性会失去XML语言的很多优点,如可读性和具有描述性的标签名字等等。
元素的PCDATA可以灵活多变,而属性值就没有这个好处了,特别是它的行结束符会被解析器转化为一个空格符。
注释:
以<!--为开始,以-->为结束。
不可以插到标签中。
在注释内容中不能有—。
注释不会被传递给应用程序,如果想要传递给应用程序,必须把有关的内容放在元素里或者属性里。
空元素:
当元素中没有PCDATA时,除了可以用传统的开始标签和结束标签来表示外,还可以用自封闭标签。
自封闭标签中>之前不能有空格,得与/紧紧相靠。
自封闭标签还可以插入属性。
XML声明语句:
- 它的功能是为其它操作系统平台声明该文件为XML文档。
- 从<?xml开始,以?>为结束。
- 声明语句必须有version属性,而encoding和standalone可选。
- 属性的顺序得按version、encoding、standalone进行。
- version的值必须为1.0或1.1。
- 声明语句必须在文档的开头,且<前面最好不要留有空格。
version属性说明文档遵循XML哪个版本,而目前的XML规范只有1.0和1.1。两者区别不大,只是在给元素命名时,它们对某些Unicode字符采取不同的处理方法,它们在某些系统里对行结束符也有不同的规定。
关于encoding属性:
字符码是指一个字符集与代表这些字符的一组二进制数字的一种一一对应关系。字符编码是指字符码中的数字表示方法。
ASCII码有两种方案:7位的和8位的。7位的是文本的一个更通用的标准,而8位的就有不同的编码方式了,不过它们的前128个字符都与7位ASCII字符码一致。
Unicode码是针对ASCII码的中所能表示的字符局限而发明的,它通过重新设计,囊括了全部人类语言中的所有字符。它主要有两种方案:UTF-8和UTF-16。后者用两个字节来表示一个字符。
UTF-8和UTF-16:
UTF-8的编码比较巧妙。它用一个字节表示7位的ASCII字符,但表示其他字符时,就得用两个以上的字节来表示,由此可知7位的ASCII码只是UTF-8的一个子集,在文档中只用到英语时采用UTF-8能生成比较小的文件。但对于其它语言,由于UTF-16始终使用两个字节表示一个字符,而UTF-8可能得使用3个甚至更多,所以在这种情况下使用UTF-16会更好。
encoding属性告诉解析器我们的文档采用哪种编码,然后解析器按照正确的编码方法读取文档,并把它们转换为Unicode字符。若没有encoding属性,则解析器使用默认的UTF-8或UTF-16来解析。
standalone属性:
- yes表示文档可以完全独立存在,不依赖于其它文件。
- no表示文档可能依赖于一个外部的DTD文件。
此属性的全称为独立文档声明(SDD)。XML推荐标准并没有要求解析器对SDD作任何处理。对解析器来说,只是起到提示的作用。
处理指令:
在文档中嵌入应用程序专用指令,它们可以控制文档的处理过程。它们不属于文档数据,但是会传递给应用程序。
在大多数情况下,应用程序根本不需要XML声明语句里的信息,它们只对解析器有用。甚至encoding属性对应用程序也没有多大用处,因为解析器在把文档传递给应用程序时,它已转换为Unicode格式,而不管文档原来采用何种编码。
非法的PCDATA字符:
PCDATA中不能有<和&,如果要使用,得额外添加引用和利用转义字符。
用“<”和“&”可以分别表示<和&,当然,如果要表示>可以用“>”。
转义字符的使用还可以扩展为&#nnn这样的字符串,其中nnn是某个字符的Unicode码(nnn为十进制数,xnnn为十六进制数)。
当要使用大量的转义字符时,文档的可读性就会比较差。而CDATA可解决这个问题。它们告诉解析器不要对它解析,让它里边的内容保持不变。在解析时,解析器会忽略这些文本,直接把它们传递给应用程序。
CDATA中可以包含空白符。
XML中的错误:
XML推荐标准除了规定解析器如何从XML文档读取信息外,还规定了解析器如何处理文档中的错误。
XML定义了两种错误:一般性错误和致命性错误。
- 一般性错误指仅违反规范中的规则,但其结果不能确定。允许XML处理器从这类错误中恢复正常,并继续处理其他内容。
- 这类错误比上一类错误要严重。当解析器遇到一个这类错误时,就不能继续正常地运行(不过它可能一直不停地处理XML文档,进一步找出文档中的其他错误)。这种错误导致了一个XML文档不可能成为一个良构的XML文档。