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

1.3 XML Schema和DTD

DTD是近几年来XML技术领域所使用的最广泛的一种模式。但是,由于DTD并不能完全满足XML自动化处理的要求,例如不能很好实现应用程序不同模块间的相互协调,缺乏对文档结构、属性、数据类型等约束的足够描述等,所以W3C于2001年5月正式推荐XML Schema为XML的标准模式。显然,W3C希望以XML Schema来作为XML模式描述语言的主流,并逐渐代替DTD。那么,从技术角度看,XML Schema与DTD有哪些区别,XML Schema又有哪些优势呢?

1.3.1 XML模式与XML格式

XML模式是指用来描述XML结构、约束等因素的语言,例如,XML Schema、DTD、XDR、SOX等。XML格式则是XML文档本身所具有的格式。这里以XML Schema来代表W3C所推荐的XML Schema模式标准,而以“XML模式”来代表所有的XML模式描述语言。

从模式描述语言来说,XML Schema和DTD都属于语法模式。与概念模式不同,语法模式在对同一事物描述时,可以采用不同的语法,例如在对关系模式描述时,无论是使用XML Schema还是DTD,都既可以用元素也可以用属性来描述关系模式的列。

模式必须以某种格式来表示,XML Schema的格式与DTD的格式有着非常明显的区别,事实上XML Schema也是XML的一种应用,也就是说XML Schema的格式与XML的格式是完全相同的,而作为SGML DTD的一个子集,DTD具有与XML格式完全不同的格式。这种区别会给XML Schema的使用带来许多好处:

● XML用户在使用XML Schema的时候,不需要为了理解XML Schema而重新学习,节省了时间。

● 由于XML Schema本身也是一种XML,所以许多的XML编辑工具、API开发包、XML语法分析器可以直接地应用到XML Schema,而不需要修改。

● 作为XML的一个应用,XML Schema理所当然地继承了XML的自描述性和可扩展性,这使得XML Schema更具有可读性和灵活性。

● 由于格式完全与XML一样,XML Schema除了可以像XML一样处理外,也可以同它所描述的XML文档以同样的方式存储在一起,方便管理。

● XML Schema与XML格式的一致性,使得以XML为数据交换的应用系统之间,也可以方便地进行模式交换。

● XML有非常高的合法性要求,DTD对XML的描述,往往也被用作验证XML合法性的一个基础,但是DTD本身的合法性却缺少较好的验证机制,必须独立处理。XML Schema则不同,它与XML有着同样的合法性验证机制。

1.3.2 数据类型

或许,对于许多开发人员来讲,XML Schema与DTD相比的一个最显著的特征,就是对数据类型的支持了。这完全是因为DTD提供的数据类型只有CDATA、Enumerated、NMTOKEN、NMTOKENS等十种内置(built-in)数据类型。这样少的数据类型通常无法满足文档的可理解性和数据交换的需要。XML Schema则不同,它内置了三十七种数据类型,如long, int, short, double等常用的数据类型,并通过将数据类型表示为由value space、lexical space和facet组成的三元组而获得更大的灵活性。但是,XML Schema数据类型的真正灵活性来自于其对用户自定义类型的支持。XML Schema提供两种方式来实现数据类型的自定义。

简单类型定义(simpleType)

这是在XML Schema内置的数据类型基础上或其他由XML Schema内置的数据类型继承或定义所得到的简单的数据类型(simpleType)基础上,通过restriction, list或者union方式定义新的数据类型。

以下三个清单定义的都是简单数据类型:

清单1-2 restriction方式的定义

        <simpleType name=' Sku' >
            <restriction base=' string' >
                <pattern value=' \d{3}-[A-Z]{2}' />
            </restriction>
        </simpleType>

清单1-3 list方式的定义

        <simpleType name=' listOfDouble' >
            <list itemType=' double' />
        </simpleType>

清单1-4 union方式的定义

            <xsd:attribute name="size">
                <xsd:simpleType>
                    <xsd:union>
                      <xsd:simpleType>
                          <xsd:restriction base="xsd:positivelnteger">
                              <xsd:minlnclusive value="1"/>
                              <xsd:maxlnclusive value="12"/>
                          </xsd:restriction>
                      </xsd:simpleType>
                      <xsd:simpleType>
                          <xsd:restriction base="xsd:string">
                              <xsd:enumeration value="month"/>
                          </xsd:restriction>
                      </xsd:simpleType>
                    </xsd:union>
                </xsd:simpleType>
            </xsd:attribute>

复合类型定义(complexType)

该方法提供了一种功能强大的复杂数据类型定义的机制,可以实现包括结构描述在内的复杂的数据类型。下面是一个以complexType定义实现关系模式中表结构的例子,假设有表T_C_Type(Psign, Count),其中Psign为CHAR数据类型,Count为NUMBER数据类型。则有:

清单1-5 complexType定义

            <! --表结构类型定义-->
            <complexType name="T_C_Type">
                <sequence minOccurs="0" maxOccurs="unbounded">
                    <element name="Psign">
                      <complexType>
                          <simpleContent>
                              <restriction base="string">
                                <attribute name="value" type="string"/>
                              </restriction>
                          </simpleContent>
                      </complexType>
                    </element>
                    <element name="Count" minOccurs="0">
                      <complexType>
                          <complexContent>
                              <restriction base="anyType">
                                <attribute name="value" type="int" use="optional"/>
                              </restriction>
                          </complexContent>
                      </complexType>
                    </element>
                </sequence>
            </complexType>

不仅如此,XML Schema还允许元素的内容取空值,这一点可以扩大XML Schema对数据情况的描述范围,而DTD却无能为力。例如:

清单1-6 XML Schema元素取空值的定义

        <element name="test" nullable="true"/>

1.3.3 元素顺序的支持

DTD与XML Schema都支持对子元素顺序的描述,但DTD没有提供对无序情况的描述,也就是如果以DTD来描述元素的无顺序出现的情况,它必须采用穷举元素各种可能出现的排列顺序的方式,这种方法不仅繁琐,有时甚至是不现实的。例如对于table的a, b子元素,如果希望它们以任意的顺序出现,用DTD来描述:

清单1-7 a, b子元素任意顺序出现的DTD定义

            <? xml version="1.0" encoding="UTF-8"? >
            <! ELEMENT ENTER_NAME_OF_ROOT_ELEMENT_HERE EMPTY>
            <! ELEMENT table ((a, b)—(b, a))>
            <! ELEMENT a  (#PCDATA)><! ELEMENT b (#PCDATA)>

XML Schema提供了<all>标记来描述这种情况:

清单1-8 a, b子元素任意顺序出现的XML Schema定义

        <xsd:element name="a" type="xsd:string"/>
          <xsd:element name="b" type="xsd:string"/>
          <xsd:element name="table">
              <xsd:complexType>
                  <xsd:all>
                      <xsd:element ref="a"/>
                      <xsd:element ref="b"/>
                  </xsd:all>
              </xsd:complexType>
       </xsd:element>

可见,用XML Schema来实现子元素的无序描述要简单得多。

1.3.4 命名空间

在XML中引入命名空间的目的是为了能够在一个XML文档中使用其他XML文档中的一些具有通用性的定义(通常是一些元素或数据类型等的定义),并保证不产生语义上的冲突。DTD并不能支持这一特性,这进一步限制了DTD的适用范围,而XML Schema却能很好地满足这一特性。

并且,XML Schema还提供了include和import两种引用命名空间的方法。下面的例子中XML Schema文档引用了其他两个XML Schema的定义,通过使用import实现了混合使用不同命名空间的目的。例子中还定义了不同命名空间中元素之间的keyref约束。

清单1-9 XML Schema对命名空间的使用

            <schema targetNamespace="http://202.117.84.144"
            xmlns:xs="http://202.117.84.144"
            xmlns="http://www.w3.org/2001/XMLSchema"
            xmlns:a="http://202.117.84.228/middlewareSqlServer2000sqlservertest2021178422
            xmlns:b="http://202.117.84.228/middlewareOracle805ioracletest20211784144"
            elementFormDefault="qualified">
            <import namespace="http://202.117.84.228/middlewareSqlServer2000sqlserverte
    st20211784228"
                schemaLocation="F:\xml schema\middlewareSqlServer2000sqlservertest20
    211784228.xsd"/>
            <import namespace="http://202.117.84.228/middlewareOracle805ioracletest202
    11784144"
            schemaLocation="F:\xml schema\middlewareOrcal805ioracletest20211784144.
    xsd"/>
            <annotation>
                <documentation xml:lang="cn">
             schema for Middleware
            Copyright 2001 Zhou Jingtao. All rights reserved.
            </documentation>
            </annotation>
            <element name="CombineDatabase">
                <complexType>
                    <sequence>
                      <element name="CombinGlobeSchema">
                          <complexType>
                              <sequence>
                                <element ref="a:H-Database"/>
                                <element ref="b:H-Database"/>
                              </sequence>
                          </complexType>
                          <keyref name="SqlServerTest_T_C_Psign" refer="b:gz_jgxx_lD_pk">
                              <selector xpath="a:H-Database/a:SqlServerTest/a:T_C/a:Count"/>
                              <field xpath="@value"/>
                          </keyref>
                      </element>
                    </sequence>
                </complexType>
              </element>
        </schema>

1.3.5 对API的支持

在使用XML技术时,DOM和SAX可能是技术人员最常使用的XML API。但是DOM和SAX只对XML实例文档有效,虽然可以通过它们实现用DTD来验证XML文档,但是DOM和SAX却没有提供解析DTD文档内容的功能,也就是说我们无法通过DOM或SAX来得到DTD中元素、属性的声明和约束的描述。然而在基于XML+DTD的数据交换过程中,一些应用程序需要得到DTD本身的描述内容和结构,以方便对XML文档中数据的处理,例如在使用关系数据库存储XML文档的过程中就涉及如何将DTD映射为关系模式描述的问题。为了实现对DTD的解析,研究人员必须为DTD开发新的接口或者专用工具,这样会带来了很多不便。

由于XML Schema本身就是一个XML文档,所以我们可以通过使用DOM、SAX或JDOM等XML API很容易地解析XML Schema,这就实现了XML文档与其描述模式处理方式的一致性,利于数据的传输和交换。

1.3.6 对于属性的定义

DTD以关键字#IMPLIED、#FIXED和#REQUIRED来指定属性是否出现,并支持属性默认值的定义。XML Schema则提供了更明确的标记来实现属性的清晰易懂的表示。XML Schema废弃了DTD的# IMPLIED,不再支持属性的隐含状态,要求必须给出明确的状态,并以prohibited来表示属性的禁用;对于默认值的表达则更为直观,用default来直接给出。

清单1-10 DTD 、XML Schema对属性的限制

        <! ATTLlST TestDTD testAr1 CDATA  #lMPLlED>
        <! ATTLlST TestDTD testAr2 CDATA  #REQUlRED>
        <! ATTLlST TestDTD testAr3 CDATA  #FlXED "3">
        <! ATTLlST TestDTD testAr4 CDATA  "3">
        <xsd:attribute name="TestAr1" type="xsd:string" use="optional" default="3"/>
        <xsd:attribute name="TestAr2" type="xsd:string" use="prohibited"/>
        <xsd:attribute name="TestAr3" type="xsd:string" use="required" fixed="3"/>

1.3.7 注释

DTD和XML Schema均支持<! -注释内容-->这样的注释方法,但是XML Schema提供了更灵活和有用的注释方式:documentation和appinfo。它们提供了面向读者和应用的注释,如清单1-11所示。

清单1-11 XML Schema的注释

            <xsd:annotation>
            <xsd:documentation>面向用户和应用的注释</xsd:documentation>
            <xsd:appinfo>
                //这是一段C语言代码。
                #include stdio.h
                void main()
                {
                    int i, j;
                    i =1;
                    j=i+1;
                }
            </xsd:appinfo>

1.3.8 对数据库的支持

目前如何将关系数据表示为XML数据及如何实现基于关系数据库的XML数据存储、查询和更新已成为研究的热点。Deutsh, Florescu, Kossman, Shanmugasundaram和D W Lee等人都在XML与关系数据的相互转化问题方面作了较为深入的研究。然而由于XML Schema成为正式推荐标准的时间较晚,加之DTD语法相对简单,所以现在大部分的研究和应用都是基于DTD展开的。但是,DTD在对关系数据的描述方面存在着明显的不足,例如DTD有限的数据类型根本无法完成对关系数据数据类型的一一映射,也无法实现大部分的数据规则的描述。XML Schema提供了更多的内置数据类型,并支持用户对数据类型的扩展,基本上满足了关系模式在数据描述上的需要,这一点可以说是XML Schema比DTD更适合描述关系数据的一个主要的原因。

通过比较,可以看出,XML Schema比DTD具有更强的表现力,能够更好地满足不同领域应用的需求。那么,是不是可以说DTD会很快被XML Schema替代并最终消失呢?从作者的观点来看,XML Schema虽然在大多数的应用领域都有替代DTD的趋势,但是DTD仍然有它的适用范围,不可能被XML Schema完全替代:

● DTD是作为XML标准的一部分发布的,W3C似乎并没有准备将其从XML标准中废除掉,对于DTD的支持还将持续。

● 目前大多数的面向XML的应用,都对DTD做了很好的支持,DTD的工具也相对较为成熟。一般情况下,这些应用和工具并不会选择以XML Schema替换DTD的方式对其升级,更多的选择应该是二者都支持。当然,对于那些对数据交换或者描述能力要求较高、DTD已不能满足功能需求的应用来说,以XML Schema代替DTD已经成为一种必然趋势。

● 当前大多数与XML模式相关的算法研究都是基于DTD展开的,作为一种研究的延续,并不会放弃DTD的研究成果,但是,针对XML Schema的研究将会成为一个新的热点。

● 在一些相对要求简单的处理环境中,DTD仍然会占有一席之地。

● 同其他技术的发展一样,由于新标准的出现,DTD的作用会逐渐减弱,但正如层次数据库在今天仍然在使用一样,对XML Schema是否会完全替代DTD做一个结论似乎为时过早。

所以,作为一种强有力的标准,XML Schema成为XML模式的主流已经成为一种趋势;但作为一种最简单的XML模式,DTD也还将会在一段时间内发挥它应有的作用。