当前位置: 首页 > 文章教程  > 计算机与互联网 > 网络编程

17.2深入认识XML文档

9/17/2020 9:31:19 PM 人评论

17.2深入认识XML文档

17.2 深入认识XML文档

和所有标记语言一样,XML也有其特定的语法格和细节部分,包括XML的声明、XML元素、XML标签及其属性、XML处理指令、XML文档中的注释以及文档定义类型等基本概念和用法。XML是一个比较简单的描述数据的方法,但并不意味着XML很简单,实际上,关于XML的内容是非常丰富的,本节将从基本和实用两个方面出发,尽可能多地介绍XML文档的各个方面。

17.2.1 XML声明

XML的作用就是告诉XML处理程序这个文件是按照XML文件的标准对数据进行描述的。当创建一个XML文件时,通常要以一个XML声明作为开始。是因为XML声明在文件中是可选内容,可加可不加,但W3C推荐加入声明,所以通常把XML声明作为XML文件的第一行。一个最简单的XML声明如下。


<?xml version = "1.0"?>

XML的声明由“<?”开始,以“?>”结束。在“<?”后面紧跟着处理指示的名称,在这里是“xml”。XML声明中要求必须指定version的属性值,这个值定义了XML的版本。另外,声明中还有两个可选属性,分别是standalone和encoding。因此,一个完整的XML声明如下所示。


<?xml version="1.0" standalone="no" encoding="UTF-8"?>

·version属性,在一个XML的声明中必须包括version属性指明所采用的XML的版本号,而且,它必须在属性列表中排在第一位。由于当前的XML最新版本是1.0,所以目前看到XML声明无一例外都是version="1.0"。

·standalone属性,这个属性表明该XML文件是否和一个独立的声明文件配套使用。如果该属性值为“yes”,说明没有另外一个配套的DTD文件(这个文件将在后续有所介绍)来配套使用。相反,如果这个属性置为“no”,则有可能有这样一个文件。

·encoding属性,所有XML语法分析器都要支持8位和16位的编码标准。而且,XML支持一个更庞大的编码集合。实际应用中常见的编码是GB2312(简体中文码)和UTF-8(Unicode Translation Format),采用哪种编码取决于XML文件中用到的字符集。在前文的例子中,使用了UTF-8编码来声明XML文档的字符集。

17.2.2 XML元素

XML元素是XML文档的精髓,元素是XML文件内容的基本单元。从语法上讲,一个元素包含一个起始标记、一个结束标记以及标记之间的数据内容。其形式是<标记>数据内容</标记>。例如如下关于国籍元素的例子。


<
国籍>
中国</
国籍>

在17.2节的例子中有关于图书名称(title)的元素如下。


<title>Learning XML</title>

元素中还可以嵌套其他元素,在17.2节的代码17-1中,books元素就嵌套了book元素,而book元素又嵌套了title、author、publisher和price元素。

在代码17-1中,books元素从文件头的声明之后开始一直到文件尾,包含了文件中的所有数据信息,这个books元素称为根元素。所有XML文件都至少包含一个形式良好的根元素。根元素又称为文件标记,紧跟在XML声明之后,根标记必须是一个非空的标记,其中包含了整个文件的数据内容。如果一个XML文档没有根元素,无论该文档包含什么样的信息,XML解析器都会拒绝它。

注意 XML中开始和结束标记之间的文字称为“字符数据”,标签内(即<>之间)的文字称为“标记”。例如<title>Learning XML</title>,Learning XML是字符数据,而title是标记。<title>和</title>都被看做是XML标签。

所有XML元素都必须有一个结束标签,忽略结束标签是不合法的。这一点和HTML完全不一样,在HTML中,有些标签可以不用对应结束标签,示例如下。


<p>This is a paragraph
<p>This is another paragraph

这里表示段落的<p>标签就没有对应的结束标签。而在XML中,每一个标签都必须有结束标签。读者可能已经注意到17.2节的示例XML文档中,表示XML声明的标签<xml>就没有结束标签。这是正确的,因为XML声明并不算是XML文档的一部分,它不是一个XML元素,所以它不应该有结束标签。

XML元素不能重叠,例如如下XML代码。


<aaa><bbb> XML
元素示例 </aaa></bbb>

这段XML代码就是错误的,因为在标签<aaa>中开始的标签<bbb>必须在标签<aaa>之内结束,如下代码才是正确的XML代码。


<aaa><bbb> XML
元素示例 </bbb></aaa>

这也就是说,XML的元素要正确地嵌套。

17.2.3 标记和属性

XML的标记和HTML的标记在形式上大体相同,符号“<”和“>”之间的内容都称为标记。其基本形式如下。


<
标记名 
属性名="
属性取值">

XML对于标记的语法规定比HTML要严格得多。首先,标记是必不可少的。任何一个形式良好的XML文件中至少要有一个元素。

注意  和HTML不同,XML对标签的大小写十分敏感。<Word>和<word>在XML中是两个不同的标签。

XML要有正确的结束标记。结束标记除了要和开始标记在拼写和大小写上完全相同,还必须在前面加上一个斜杠“/”。例如,如果开始标记是<ADDRESS>,结束标记应该是</ADDRESS>。

因为XML严格要求开始标记和结束标记匹配,所以,HTML中的<BR>、<HR>的元素形式在XML中是不合法的。但是,当一对标记之间没有任何文本内容时,可以不写结束标记,而在开始标记的最后惯以斜杠“/”来确认,这样的标记称为“空标记”。例如,HTML中的标记<HR>在XML中的使用方式应该是<HR/>。

标记名称要合法,标记应该以字母、下划线“_”或冒号“:”开头,后面跟字母、数字、句号“.”、冒号、下划线或连字符“-”,中间不能有空格,而且任何标记不能以“xml”起始。不过,最好不要在标记的开头使用冒号,尽管它是合法的,但可能会带来混淆。另外,在XML1.0标准中,允许使用任何长度的标记,不过,现实中的XML处理程序可能会要求标记的长度在一定范围内。

XML中可以为标签指定属性和属性的值,就像HTML中那样。XML文档中的属性有两个主要规则,其一,属性必须有值;其二,属性值必须用引号括起,属性值可以使用单引号、双引号括起,但要始终保持一致。如果属性值包含单引号或双引号,则可以使用另一种引号来括起该值(如name="Doug's car"),或使用实体&quot;代表双引号,使用&apos;代表单引号。

注意 实体是一个符号(如&quot;),XML解析器会用其他文本代替该符号。

XML标记中可以包含任意多个属性。在标记中,属性以“名称/值”对的形式出现,属性名不能重复,属性名与属性值之间用等号“=”分隔,且取值用引号括起来,示例如下。


<person sex="female">

这段代码为标签person的sex属性取值为female。

17.2.4 注释

注释可以出现在XML文档的任何位置,甚至可以出现在根元素的前面或后面。XML文档注释以<!--开始,以-->结束,这个用法和HTML一致。例如下面的XML代码片段中使用了注释。


     01 <!-- 
这些是图书的有关信息 -->
     02 <book>
     03     <title>Learning PHP5</title>    <!-- 
图书的名称 -->
     04     <author>David</author>
     05     <publisher>White Water Press</publisher>
     06     <price>29.90</price>
     07 </book>
     08 <!-- 
图书信息结束 -->

【代码解析】这段XML代码片段中加入了3处注释。

注意 在注释文本中不能出现“-”或“--”,因为XML处理器可能把它们和注释结尾标志“-->”相混淆。

不要把注释文本放在标记之中,如代码将注释“<!--这些是图书的有关信息-->”放在了标签<book>之中,这是错误的。


     <book  <!-- 
这些是图书的有关信息 --> >
         <title>Learning PHP5</title>
         <author>David</author>
         <publisher>White Water Press</publisher>
         <price>29.90</price>
     </book>

同样的道理,不要将注释放在实体声明中,也不要放在XML声明之前。前面的内容讲过,XML声明永远是XML文件中的第一行。

注意 注释是不能嵌套使用的。

在使用一对注释符号表示注释文本时,要保证其中不再包含另一对注释符号。例如如下示例是不合法的。


     <book>
         <title>Learning PHP5</title>
         <!-- 
以下是图书作者的信息 
             <!-- 
作者的姓名 --> 
         -->
         <author>David</author>
         <publisher>White Water Press</publisher>
         <price>29.90</price>
     </book>

说明 XML解析器对于注释中的一切内容都会视而不见,注释中出现的标记也一同被忽略。这为一下除去XML文档中的一大部分元素提供了一种方法,可以将这部分元素使用注释括住。

17.2.5 处理指令

处理指令是用来给处理XML文档的应用程序提供信息的。也就是说,XML分析器可能对它并不感兴趣,而把这些信息原封不动地传给XML应用程序。这个应用程序应该会解释这个指示,按照它所提供的信息进行处理,或者再把它原封不动地传给下一个应用程序。正如前面所看到的,XML声明就是一个处理指令。

XML有很多处理指令,它们都遵循如下所示的格式。


<?
处理指示名 
处理指示信息?>

例如代码17-1中的XML声明<?xml version="1.0"encoding="GB2312"?>就是一个处理指令。由于XML声明的处理指示名是“xml”,因此其他处理指示名不能再用“xml”。例如下面的代码,是另外一个处理指令。


<?cocoon-process type="sql"?>

cocoon是来自Apache软件基金会(Apache Software Foundation)的XML处理框架。当cocoon处理XML文档时,它会寻找以cocoon-process开头的处理指令,然后相应地处理XML文档。在该示例中,type="sql"属性告诉cocoon,XML文档包含一个SQL语句。

17.2.6 实体简介

在前面介绍标记属性时,提到了实体这一概念,本小节对实体再做一些简要的说明。可以这样理解实体,实体是文档用来替换一些特殊标记符号的字符串。XML中或HTML中常见的实体如下所示。

·实体<代表小于符号<,lt就表示less than。

·实体>代表大于符号>,gt就表示greater than。

·实体"代表一个双引号”。

·实体'代表一个单引号'(或撇号)。

·实体&代表一个“与”符号&。

注意 实体以符号“&”开头,以英文分号“;”结束。

17.2.7 文件类型定义

通过对前面内容的学习,读者应该了解到,XML的精髓是基于信息描述的、能够体现数据信息之间逻辑关系的、可以确保文件的易读性和易搜索性的自定义标记。一个完全意义上的XML文件不仅应该是“形式良好的”,而且还应该是使用了自定义标记的XML文件。定义用来表示数据的标记,最常用的方法就是实用文档定义类型(Document Type Definition),即所谓的DTD。

DTD指定在XML文档中出现的元素、这些元素出现的次序、元素相互嵌套的关系以及XML文档结构的其他详细信息,DTD是XML规范的一部分。一个XML文件必须遵守文件类型描述DTD(Document Type Definition)中定义的种种规定。DTD定义了文件的整体结构以及文件的语法。简而言之,DTD规定了一个语法分析器为了解释一个“有效的”XML文件所需要知道的所有规则的细节。这些规则有时很简单,有时会很复杂。比如说,列出所有有效的元素、标记、属性和实体,这就是一个比较简单的规则。又如,指出元素之间的内在联系,说明某个元素必须包含的其他元素,就是一个比较复杂的规则。

DTD用来指定XML文档的基本结构,最简单的使用DTD的方法是在XML文件的序言部分加入一个DTD描述,加入的位置紧接在XML处理指示之后,其结构如下。


     <?xml version = "1.0" encoding="UTF-8">
     <!DOCTYPE 
根元素名[
元素描述
         ]>
文件体

这段代码表示该XML文档实用DOCTYPE中规定的“根元素名”作为其根元素的名字。一个DTD不仅要告诉XML分析器该XML文件的根元素是什么,而且还要告诉语法分析器文件的内容和结构,说清文件结构中的每一个细节。为了描述这些细节,必须展开DTD中元素说明部分,使用元素类型声明(Element Type Definition,ETD)来声明所有有效的文件元素。ETD结构如下。


<!ELEMENT 
元素名 
元素内容描述>

在上述例子中,可以通过如下方式定义“图书信息”这个元素。


     <?xml version = "1.0" encoding="UTF-8">
     <!DOCTYPE books[
图书信息
     <!ELEMENT books ANY>
     ]>
     <books>
     </books>

这个DTD定义XML文件只有一个根元素,ANY表示这个元素可以有任何类型的子元素,也可以是纯文本,还可以为空。

注意 除了根元素外,在定义其他元素时使用关键字ANY都是不好的习惯。

通常需要在XML文档中的根元素之内加入其他元素,这个XML文档才是有效的,才是可以被XML解释器所能接受的XML文档。

为了使元素“books”中还可以包含其他元素,还需要定义元素“book”(即具体的图书)和元素“title”(即图书的名称),代码如下。


     <?xml version = "1.0" encoding="UTF-8">
     <!DOCTYPE books[
图书信息
     <!ELEMENT books (book)>
     <!ELEMENT book (title)>
     <!ELEMENT title (#PCDATA)>
     ]>
     <books>
         <book>
             <title>Learning PHP5</title>
         </book>
     <books>

至此,已经定义了一个XML文档,它还有一个名为books的根元素,根据DTD的描述,该根元素中可以包含book元素,book元素又包含子元素,名为title。而title只能包含纯文本数据,这在DTD中用#PCDATA来体现。如下是一个加入了DTD描述的较为完整的XML文档示例,它以代码17-1为基础。


     01 <?xml version = "1.0" encoding="UTF-8">
     02 <!DOCTYPE books[
     03     
图书信息
     04 <!ELEMENT books (book)*>
     05 <!ELEMENT book (title,author,publisher,price)>
     06 <!ELEMENT title (#PCDATA)>
     07 <!ELEMENT author (#PCDATA)>
     08 <!ELEMENT publisher (#PCDATA)>
     09 <!ELEMENT price (#PCDATA)>
     10 ]>
     11 
     12 <books>
     13     <book>
     14         <title>Learning PHP5</title>
     15         <author>David</author>
     16         <publisher>White Water Press</publisher>
     17         <price>29.90</price>
     18     </book>
     19     <book>
     20         <title>Learning XML</title>
     21         <author>Jeffson</author>
     22         <publisher>White Water Press</publisher>
     23         <price>50.79</price>
     24     </book>
     25 <books>

【代码解析】在这个XML文档中读者还可以看到其他一些符号,这些符号用来指定元素在XML出现的次数,如<!ELEMENT books(book)*>,这里的*表示<books>元素必须包含0个或多个book元素。星号表示这一项可以出现任意次,包括零次。表17-1列举了DTD中可以使用的一些符号及其解释。

表17-1 DTD中使用的特殊字符及其含义解释

这些符号的使用都类似于正则表达式,例如<!ELEMENT addressbook(address+)>,表示<addressbook>元素包含一个或多个<address>元素。可以有任意多的<address>元素,但必须至少有一个。加号表示这一项可出现任意次,但至少出现一次。

使用DTD也可以定义属性。在DTD中定义属性时,格式如下。


<!ATTLIST 
元素名 
(属性名 
属性类型 
默认值)*>

使用DTD可以完成的对属性的定义功能如下所述。

·定义哪些属性是必需的

·定义属性的默认值

·列出给定属性的所有有效值

如下是一个使用DTD定义属性的示例代码。


     <!ELEMENT city (#PCDATA)>
     <!ATTLIST city province CDATA #REQUIRED>

这段示例XML代码定义了<city>元素,同时使用关键字ATTLIST声明元素的属性。属性列表中的名称city告知解析器这些属性是为元素<city>定义的。名称province是属性的名称,关键字CDATA和#REQUIRED告诉XML解析器province属性包含文本并且是必需的。如果是可选的,可以使用CDATA#IMPLIED。

XML中,关于DTD的内容是相当丰富的,本书只是略微介绍了DTD的一些基本概念和基础用法,更深更多的内容并没有涉及,有兴趣的读者可以参考有关XML的专门文献进行学习。

上一篇:17.1认识XML

下一篇:17.3在PHP中处理XML

相关教程

共有条评论 网友评论

验证码: 看不清楚?