实用XML应用开发技术
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

1.4 关于XML的几点说明

“可扩展标记语言”已经存在了相当长的一段时间,因此现在大多数人都熟悉其最基本的需求:所有XML文档都必须既要格式正确又要有效。但如何确定你的XML文档满足了这些需求呢?简短的回答就是不需要你人为地去检查,而是要依赖XML语法分析器(又称XML语法解析器)来为你处理这问题。

目前市场上到处都充斥着XML语法分析器,其中大多数都可以从Web上免费获得。一个基本的XML语法分析器应该既强调XML语法规则(即,确保文档格式正确),又能检验文档的有效性。XML语法分析器可用于几乎所有的相关的计算机语言,包括C、C++、Perl、Python、Tcl和Java。

谈到确保XML格式正确时,你可以或多或少地指向一个语法分析器来执行。然而为了确保文档有效,需要为语法分析器提供XML Schema或DTD。

下面将首先阐述XML文档格式的正确性,然后会谈到较少讨论的话题,具体地说,就是DTD。我将讨论为什么需要将DTD包含在XML文档中、介绍一些最常用的DTD语法,并使用几个简单的样本来教你开始编写自己的DTD。

为什么要格式正确

当XML开发人员谈到格式正确和格式不正确的XML时,并不是进行美学讨论。只有格式正确的XML文档,才能被XML语法分析器处理。格式正确的XML文档需要满足以下三个基本结构需求:

● 有一个包含所有其他元素的父(或根)元素。

● 每个开始标记都有相对应的结束标记。

● 所有元素都正确嵌套。

清单1-12是一个格式正确的XML示例。请注意,该文档的父元素是<person>,每个开始标记都有一个结束标记,并且每个结束标记都有与其开始标记完全相同的定义。通常,开始标记和结束标记之间包括的是信息或文本。不过,在某些情况下,标记之间没有包括信息或文本。空标记必须用一个右斜杠来结束。<nothing/> 就是一个空标记。

清单1-12格式正确的XML

            <person>
                <firstname>Jane</firstname>
                <lastname>Fung</lastname>
                <nothing/>
            </person>

清单1-13是一个格式不正确的XML示例。它举例说明了三种常见错误。首先,开始和结束 <firstname> 标记没有完全匹配。其次,<lastname>标记没有结束标记。最后,空标记没有用一个右斜杠结束。

清单1-13格式不正确的XML

        <person>
            <Firstname>Jane</firstname>
            <lastname>Fung
            <nothing>
        </person>

清单1-14也是一个格式不正确的XML示例。它举例说明了未正确嵌套的错误。<person>和<employee>之间不是嵌套,而是交叉关系。应该是</employee>位于</person>之前,或者<person>位于<employee>之后。

清单1-14格式不正确的XML

        <employee>
            <person>
                <firstname>Jane</firstname>
                <lastname>Fung</lastname>
                <nothing>
        </employee>
        </person>

DTD中有什么内容

XML的优点在于它允许你定义自己的有意义的标记,因此你可以最大程度地定制文档。但XML就是XML(可扩展),而人就是人(疯狂的人),这可能很快就会使XML包含很多标记而无法控制,以致使用者可能因为混淆而无法理解。解决方案是DTD(XML Schema),它指定了XML文档的标记,以及它们之间的制约关系。简而言之,DTD指定:可以在文档中存在的元素、哪些元素可以具有属性、在元素内部元素的层次结构以及元素在整个文档中出现的顺序。

虽然DTD(XML Schema)不是必需的,但它们确实带来方便。DTD有三个基本用途,它能:

● 对标记编制文档。

● 加强标记参数内部的一致性。

● 使用XML语法分析器能够验证文档。

如果为某XML文档指定DTD,则受这个DTD约束的XML文档称为有效的XML文档;如果不为其指定DTD,则不受DTD约束,这时的XML文档称为无效的XML文档。无论XML文档是否有效,只要格式正确,都可以由XML语法分析器进行分析处理。只要XML文档是有效的,那么它必须符合DTD的规定;否则用语法分析器处理时会报错。

关于示例的几点说明

清单1-15中DTD的第一行定义了XML文档的父元素:person。person元素有两个子元素:firstname和lastname。

第二和第三行包含了元素属性#PCDATA,它表明firstname和lastname元素可能包含了经过语法分析的字符数据(在这种情况下是文本)。DTD文件的最后一行描述了一个空标记:nothing。

清单1-15 精简person.xml的DTD

        <! ELEMENT person (firstname, lastname)>
        <! ELEMENT firstname (#PCDATA)>
        <! ELEMENT lastname (#PCDATA)>
        <! ELEMENT nothing EMPTY>

从清单1-15中的DTD可以看出,任何阅读这个XML文档的人(以及对它进行语法分析的语法分析器)都知道person元素仅包含两个文本元素:firstname和lastname。此外,DTD规定在整个文档中firstname元素必须在lastname元素之前出现。

下一章讲述的DTD语法快速指南中,定义了一些最常用的DTD语法元素,可以帮助你定义较为复杂的DTD。可以在W3C主页上找到完整的DTD规范。

关于XML的几点说明

对XML的深入探讨主要考虑的是文档头中的几个元素,从以下开始:

        <? xml version="1.0"? >

每个XML文档都必须包含这样的一个头,对XML语法分析器表示它是一个XML文档。下一行告诉XML语法分析器该文档是使用什么字符编码来创建的:

        <! DOCTYPE people SYSTEM "people.dtd">

在Unix系统上创建的XML文档和在Windows系统上创建的XML文档可能有不同的编码。

还可以为第一行设置可选的standalone属性。standalone的默认值是no, no值表示该DTD定义是在另一个文件中描述的。yes值表明该DTD应该在XML文档内部定义。我没有为示例设置这个属性;如果想设置,它应该看起来如下:

        <? xml version="1.0" standalone="yes"? >
        <! DOCTYPE people [
            <! ELEMENT people (person+)>
            <! ELEMENT person (#PCDATA)>
        ]>

还应该注意使用这个文档格式正确的方法。例如,所有空标记都用一个右斜杠结束,如下所示:

        <townhouse townhouse_type="good" />

另外还要注意,CDATA用于将所有如果不进行转义就会以XML语言解释的数据进行转义,例如:

        <! [CDATA[<greeting>5000</greeting>]]>

如果进行适当的格式化,这一行将以文本内容显示:

        <greeting>5000</greeting>

这里,对XML文档做了一些简单描述。我们将在下一章中详细介绍XML Schema,包括语法、数据类型等,并将在第3章中通过实例来描述XML Schema和XML文档。通过前三章的学习,读者将学会如何设计XML Schema/DTD和编写XML文档,这是XML应用的第一步。