《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中不能有<和&,如果要使用,得额外添加引用和利用转义字符。

用“&lt;”和“&amp;”可以分别表示<和&,当然,如果要表示>可以用“&gt;”。

转义字符的使用还可以扩展为&#nnn这样的字符串,其中nnn是某个字符的Unicode码(nnn为十进制数,xnnn为十六进制数)。

当要使用大量的转义字符时,文档的可读性就会比较差。而CDATA可解决这个问题。它们告诉解析器不要对它解析,让它里边的内容保持不变。在解析时,解析器会忽略这些文本,直接把它们传递给应用程序。

CDATA中可以包含空白符。

XML中的错误:

XML推荐标准除了规定解析器如何从XML文档读取信息外,还规定了解析器如何处理文档中的错误。

XML定义了两种错误:一般性错误和致命性错误。

  • 一般性错误指仅违反规范中的规则,但其结果不能确定。允许XML处理器从这类错误中恢复正常,并继续处理其他内容。
  • 这类错误比上一类错误要严重。当解析器遇到一个这类错误时,就不能继续正常地运行(不过它可能一直不停地处理XML文档,进一步找出文档中的其他错误)。这种错误导致了一个XML文档不可能成为一个良构的XML文档。

 

 

时间: 2024-10-06 16:34:06

《XML入门经典》学习进程之第2章良构的XML文档的相关文章

《XML入门经典》学习进程之第3章命名空间

在XML解析器把XML文档解析并将其中的数据传递给应用程序后,应用程序需要把来自不同文档的元素组合到同一个XML文档里. 无论是在同一个文档还是在不同的文档,为了解决命名冲突的问题,可以在每个元素前添加前缀.但这个方法也有缺点,就是在为HTML的XML版的元素前添加前缀时,浏览器可能无法正常读取XML文档中的XHTML内容. 命名空间只是起到"分装容器"的作用,除此之外,无任何意义. 命名空间的定义有了,但是由谁来管理这些命名空间?要使命名空间有效,命名空间前缀本身也必须是唯一的.这个

《Java开发手册》学习进程之第7章访问控制符

类的访问控制符: 虽然访问控制符有四种,但针对外部类来说,只需要公共的和默认的就够了. public表示任何类都可以使用该类. 当一个类被定义为public的时候,它就可以在任何类里被访问了. 成员的访问控制: 成员(即成员变量和方法)能被其他类访问主要取决于两个方面因素: 成员变量和方法所在类的可见性是其能被正常访问的前提条件: 其次是成员变量和方法的访问控制符直接决定了是否可以被访问. Static关键字:  Java中没有全局变量的概念. 若static修饰成员变量,当生成类的对象时,该类

《Java开发手册》学习进程之第9章接口

接口中的成员变量: 与类不同,在接口中只能定义常量属性,并且可以不必使用public.statict和final修饰,因为即使不使用这些修饰符,编译时也会为其加上,即接口中的成员变量隐含的是"public static final"的.另外,必须在声明的同时给出其值. 接口中的方法: 接口中的方法必须是抽象的,原因是接口只是代表了一个契约,表示实现它的类有什么样的功能,具体实现是由实现它的类完成的. 接口中的方法必须是public.abstract的,不能像接口中的成员变量一样使用fi

《Java开发手册》学习进程之第16章多线程

多线程编程可以使程序具有两条或两条以上的并发执行线索,就像日常工作中由多人同时合作完成一个任务一样.这在很多情况下可以改善程序的响应性能,提高资源的利用效率. 例如,开发一个网上购物时自动邮件通知的程序,在用户单击"提交"按钮确认订单时,一方面要显示信息提示用户订单已确认,一方面应该自动给用户发送一份电子邮件. 如果是单线程模式,则需要等待邮件发送完成之后,再显示提示信息,由于邮件发送的过程相对较慢,用户可能要经过漫长的等待才看到确认信息,界面响应性能不是很好. 而显示订单确认信息与发

《Java开发手册》学习进程之第6章对象和类

传统的过程化程序设计通过设计一系列的过程——算法来求解问题.这些过程一旦被确定,下一步就要开始寻找存储数据的方式,即“程序 = 算法 + 数据结构”.而面向对象的程序设计(即OOP,Object Oriented Programming)调换了这个次序,将数据放在第一位,之后再考虑操纵数据的算法. 在OOP中,程序被看作是相互协作的对象集合,每个对象都是某个类的实例.所有类构成了一个通过继承关系相联系的层次结构. 由于面向过程的编程模式是先将一系列过程(即函数)设计好再通过参数输入求解的,所以对

《Java开发手册》学习进程之第4章控制流程语句

在多重选择:switch语句中,switch(a)中的a可以为基本类型表达式,也可以为枚举类型表达式.而case后面所跟的表达式也是要满足以下条件的: 与a的表达式相兼容 自身应为不能有变量(即只能有字面值或者final的变量) 不能有两个相同的case 另外,要注意switch语句的根本执行流程:switch将判断表达式的值与case后面的表达式的值进行匹配,若找到匹配的case,则从此case开始执行,若没有匹配到相应的case,而遇到了default,则从default开始执行,直到遇到b

《Java开发手册》学习进程之第2章基本数据类型

2.1  数据类型 Java表示整数常量时,默认情况下为int型:若整数常量前面有个0,则表示八进制数:若整数常量前面有个‘0x’或’0X’,则表示十六进制. long型常量需在后面加个’l’或’L’.用System.out.println()方法输出时,其后缀名并不会输出. 如果某个浮点值没有使用float关键字(’f‘或’L‘)作为后缀名,则系统默认为double型.同long型常量一样,其后缀名也并不会输出. 注意:别把double型的常量赋值给float型的变量,把长度为8字节的doub

《Java开发手册》学习进程之第3章运算符详解

运算符重载是指同一个运算符在不同的情况下执行不同的操作. 例如,"+"运算符在Java中就有不同的功能: 加法运算 数值正号 字符串连接 特别要注意要在字符串连接的表达式中字符串与其他基本数据类型的变量的连接问题. 例如: (1)System.out.println(a + m + n)中,a为一String对象,m和n为int型变量(也可以是byte,short,float等其他基本数据类型).根据此表达式中的运算符优先级可知,a先与m相连接,其合并为一个字符串,然后再与n连接并以字

《Java开发手册》学习进程之第10章构造器应用

构造器与返回类型: 构造器没有返回类型,若将返回值类型(包括void)添加到构造器上,编译不会报错,但此时不再是构造器了,而只是一个与所在类同名的方法而已. 构造器与方法是两个不同的概念: 构造器不能像方法一样能被对象引用调用. 构造器是创建对象时需执行的代码,由new调用.方法是类或对象具有的行为,由引用调用. 无参数的构造器(资料来源:<Java核心技术卷1(中文第9版)>127页): 如果在编写一个类时没有编写构造器,那么系统就会提供一个无参数的构造器.这个构造器将所有实例域设置为默认值