XML Schema 與 XML DTD的技術比較與分析
最後更新:2018-07-24
來源:互聯網
上載者:User
周競濤 (zhoujtnet@yahoo.com.cn)西北工業大學CAD/CAM國家專業實驗室
王明微 (wangmv@hotmail.com)西北工業大學CAD/CAM國家專業實驗室
2002 年 7 月 01 日
XML DTD是目前使用最廣泛的一種XML 模式,XML Schema則已經成為W3C的正式推薦標準,並有替代XML DTD的趨勢。那麼,從技術角度看,XML Schema與XML DTD有那些區別,XML Schema又有那些優勢呢。
引言
XML DTD(XML的文件類型定義)是近幾年來XML技術領域所使用的最廣泛的一種模式。但是,由於XML DTD並不能完全滿足XML自動化處理的要求,例如不能很好實現應用程式不同模組間的相互協調,缺乏對文檔結構、屬性、資料類型等約束的足夠描述等等,所以W3C於2001年5月正式推薦XML Schema為XML 的標準模式。顯然,W3C希望以XML Schema來作為XML模式描述語言的主流,並逐漸代替XML DTD。那麼XML Schema與XML DTD相比到底有哪些優勢呢,XML DTD是否真的會在XML的模式描述領域中逐漸消失呢。
回頁首
XML模式與XML格式
XML模式是指用來描述XML結構、約束等因素的語言,例如XML Schema、XML DTD、XDR,SOX等等。XML格式則是XML文檔本身所具有的格式。本文以XML Schema來代表W3C所推薦的XML Schema模式標準,而以"XML模式"來代表所有的XML模式描述語言。
從模式的描述語言來說,XML Schema和XML DTD都屬於文法模式。與概念模式不同,文法模式在對同一事物描述時,可以採用不同的文法,例如在對關係模式描述時,無論是使用XML Schema還是XML DTD,都既可以用元素也可以用屬性來描述關係模式的列。
模式必須以某種格式來表示,XML Schema的格式與XML DTD的格式有著非常明顯的區別,XML Schema事實上也是XML的一種應用,也就是說XML Schema的格式與XML的格式是完全相同的,而作為SGML DTD的一個子集,XML 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有非常高的合法性要求,XML DTD對XML的描述,往往也被用作驗證XML合法性的一個基礎,但是XML DTD本身的合法性卻缺少較好的驗證機制,必需獨立處理。XML Schema則不同,它與XML有著同樣的合法性驗證機制。
回頁首
資料類型
或許,對於許多開發人員來講,XML Schema與XML DTD相比的一個最顯著的特徵,就是其對資料類型的支援了。這完全是因為XML DTD提供的資料類型只有CDATA 、Enumerated、NMTOKEN 、NMTOKENS等十種內建(built-in)資料類型。這樣少的資料類型通常無法滿足文檔的可理解性和資料交換的需要。XML Schema則不同,它內建了三十七種資料類型,如long,int,short,double等常用的資料類型,並通過將資料類型表示為由value space、lexical space和facet三部分組成的三元組而獲得更大的靈活性。但是, XML Schema資料類型的真正靈活性來自於其對使用者自訂類型的支援。XML Schema提供兩種方式來實現資料類型的定義。
1)簡單類型定義(simpleType),即在XML Schema內建的資料類型基礎上或其它由XML Schema內建的資料類型繼承或定義所得到的簡單的資料類型(simpleType)基礎上,通過restriction,list 或者 union方式定義新的資料類型。
例如:
源碼1 restriction方式的定義<simpleType name='Sku'>
<restriction base='string'>
<pattern value='/d{3}-[A-Z]{2}'/>
</restriction>
</simpleType>
源碼2 list方式的定義<simpleType name='listOfDouble'>
<list itemType='double'/>
</simpleType>
源碼3 union方式的定義<xsd:attribute name="size">
<xsd:simpleType>
<xsd:union>
<xsd:simpleType>
<xsd:restriction base="xsd:positiveInteger">
<xsd:minInclusive value="1"/>
<xsd:maxInclusive 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>
2) 複合類型定義(complexType),該方法提供了一種功能強大的複雜資料類型定義機制,可以實現包括結構描述在內的複雜的資料類型。下面是一個以complexType定義實現關係模式中表結構的例子,設有表T_C_Type(Psign,Count),其中Psign為CHAR資料類型,Count為NUMBER資料類型。則有:
源碼4 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對資料情況的描述範圍,而XML DTD則無能為力。例如:
源碼5 XML Schema 元素取空值的定義<element name='test' nullable='true'/>
回頁首
元素順序的支援
XML DTD與XML Schema 都支援對子項目節點順序的描述,但XML DTD沒有提供對於無序情況的描述,也就是如果以XML DTD來描述元素的無順序出現情況,它必須採用窮舉元素各種可能出現的排列順序的方式來實現,這種方法不僅繁瑣,有時甚至是不現實的。例如對於table的a,b子項目,如果希望它們以任意的順序出現,用XML DTD來描述:
源碼6 a,b子項目任意順序出現的XML 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>標記來描述這種情況:
源碼7 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來實現子項目的無序描述要簡單的多。
回頁首
命名空間
在XML中引入命名空間的目的是為了能夠在一個XML文檔中使用其它XML文檔中的一些具有通用性的定義(通常是一些元素或資料類型等的定義),並保證不產生語義上的衝突。XML DTD並不能支援這一特性,這進一步限制了XML DTD的適用範圍。而XML Schema則很好的滿足了這一點。
並且, XML Schema還提供了include 和 import兩種引用命名空間的方法。下面的例子中XML Schema文檔引用了其它兩個XML Schema的定義,通過使用import實現了混合使用不同命名空間的目的。例子中還定義了不同命名空間中元素之間的keyref約束。
源碼8 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/middlewareSqlServer2000sqlservertest20211784228"
xmlns:b="http://202.117.84.228/middlewareOracle805ioracletest20211784144"
elementFormDefault="qualified">
<import namespace="http://202.117.84.228/middlewareSqlServer2000sqlservertest20211784228"
schemaLocation="F:/xml schema/middlewareSqlServer2000sqlservertest20211784228.xsd"/>
<import namespace="http://202.117.84.228/middlewareOracle805ioracletest20211784144"
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_ID_pk">
<selector xpath="a:H-Database/a:SqlServerTest/a:T_C/a:Count"/>
<field xpath="@value"/>
</keyref>
</element>
</sequence>
</complexType>
</element>
</schema>
回頁首
對於API的支援
在掌握和使用XML技術時,DOM和SAX可能是技術人員最常使用到的XML API。DOM和SAX只對XML執行個體文檔有效,雖然可以通過它們實現以XML DTD來驗證XML文檔,但是DOM和SAX卻沒有提供解析XML DTD文檔內容的功能,也就是說我們無法通過DOM或SAX來得到DTD中元素、屬性的聲明和約束的描述。但是在基於XML+DTD的資料交換過程中,一些應用程式需要得到DTD本身的描述內容和結構,以方便對XML文檔中資料的處理,例如在使用關聯式資料庫儲存XML 文檔的過程中就涉及到如何將XML DTD映射為關係模式描述的問題。為了實現對XML DTD的解讀,研究人員必須為XML DTD開發新的介面或者專用工具,帶來了很大的不便。
由於XML Schema本身就是一個XML 文檔,所以我們可以通過使用DOM、SAX或JDOM等XML API很容易的解析XML Schema,這就實現了XML文檔與其描述模式處理方式的一致性,利於資料的傳輸和交換。
回頁首
更加清晰的屬性出現情況的限制、以及預設值和枚舉
XML DTD以關鍵字#IMPlIED、#FIXED和#REQUIRED來指定屬性是否出現,並支援屬性預設值的定義。XML Schema則提供了更明確的標記來實現清晰易懂的表示。XML Schema廢棄了XML DTD的#IMPlIED,不再支援屬性的隱含狀態,而要求必須給出明確的狀態,並以prohibited來表示屬性的禁用。對於預設值的表達則更為直觀,用default來直接給出。
源碼9 XML DTD 、XML Schema對屬性出現情況的限制<!ATTLIST TestDTD testAr1 CDATA #IMPLIED>
<!ATTLIST TestDTD testAr2 CDATA #REQUIRED>
<!ATTLIST TestDTD testAr3 CDATA #FIXED "3">
<!ATTLIST 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"/>
對於XML Schema在枚舉方面的改進,請參見參考資料中"XML 問題 #7 W3C XML Schema 與文件類型定義 (DTD) 比較"一文(文獻9)。
回頁首
注釋
XML DTD和XML Schema都支援<!-注釋內容-->這樣的注釋方法,但是XML Schema提供了更靈活和有用的注釋方式:documentation和appinfo。它們提供了面向讀者和應用的注釋。
源碼10 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>
回頁首
對資料庫的支援
目前如何將關係資料表示為XML資料和如何?基於關聯式資料庫的XML資料存放區、查詢和更新已經成為了研究的熱點。Deutsh,Florescu[5],Kossman[5],Shanmugasundaram[6,7]和D W Lee[8]等人都在XML與關係資料的相互轉化問題方面作了較深入的研究。然而由於XML Schema成為正式推薦標準的時間較晚,加之XML DTD文法相對簡單,所以現在大部分的研究和應用都是基於XML DTD展開的。但是,XML DTD在對關係資料的描述方面明顯存在著不足,例如XML DTD有限的資料類型根本無法完成對關係資料資料類型的一一映射,也無法實現大部分的資料規則的描述。XML Schema提供了更多的內建資料類型,並支援使用者對資料類型的擴充,基本上滿足了關係模式在資料描述上的需要,這一點可以作為XML Schema比XML DTD更適合描述關係資料的一個主要的原因。
回頁首
一個結論
通過比較,可以看出,XML Schema比XML DTD具有更強的表現力,能夠更好的滿足不同領域應用的需求。那麼,是不是可以說XML DTD會很快被XML Schema替代並最終消失呢。從作者的觀點來看,XML Schema雖然在大多數的應用領域都有替代XML DTD的趨勢,但是XML DTD仍然有它的適用範圍,並不可能被XML Schema完全替代:
XML DTD是作為XML 標準的一部分發布的,W3C似乎並沒有準備將其從XML標準中廢除掉,對於XML DTD的支援還將持續。
目前大多數的面向XML應用,都對XML DTD做了很好的支援,XML DTD的工具也相對較為成熟,一般情況下,這些應用和工具並不會選擇以XML Schema替換XML DTD的方式對其升級,更多的選擇應該是二者都支援。當然,對於那些對資料交換或者描述能力要求較高、XML DTD已不能滿足功能需求的應用來說,以XML Schema來代替XML DTD已經成為一種必然趨勢。
當前大多數與XML 模式相關的演算法研究都是基於XML DTD展開的,作為一種研究的延續,並不會放棄XML DTD的研究成果,但是,針對XML Schema的研究將會成為一個新的熱點。
在一些相對要求簡單的處理環境中,XML DTD仍然會佔有它的一席之地。
同其他技術的發展一樣,由於新標準的出現,XML DTD的作用會逐漸減弱,但正如層次資料庫在今天仍然在使用一樣, 對XML Schema是否會完全替代XML DTD做一個結論似乎為時過早。
所以,作為一種強有力的標準,XML Schema作為XML模式的主流已經成為一種趨勢;但作為一種最簡單的XML模式,XML DTD也還將會在一段時間內發揮它應有的作用。
附註:
DTD和Schema
有人會問,DTD和Schema都是對XML文檔的一種約束,為什麼不就選其中之一,而又有Schema呢。因為DTD安全度太低了,也就是說它的約束定義能力不足,無法對XML執行個體文檔做出更細緻的語義限制。其實細心的人會發現,在DTD中,只有一個資料類型,就是PCDATA(用在元素中)和CDATA(用在屬性中),在裡面寫日期也行,數字還行,字元更是沒問題。而Schema正是針對這些DTD的缺點而設計的,Schema是完全使用XML作為描述手段,具有很強的描述能力,擴充能力和處理維護能力等。下面讓我們看一個簡單的例子吧:
hello.xml
-------------------
<?xml version="1.0"?>
<greeting>Hello World!!</greeting>
說明:
一個根項目:greeting;且這個元素不含屬性,無子項目,內容是字串。
hello.xsd
----------
<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="greeting" type="xsd:string"/>
</xsd:schema>
說明:
XML Schema文檔尾碼名是.xsd,完全符合XML文法,根項目是schema,命名空間xmlns:xsd="http://www.w3.org/2001/XMLSchema,用元素<element>定義執行個體文檔中的元素,如greeting。xsd:string就是定義的資料類型了,其中的資料類型有很多,比如:int,double,dateTime,Boolean,long,integer,float,等,總之Java等語言裡有的資料類型它都有,但要以“xsd:”開頭。