由于項目需要對大量的XML文件進行處理,而自己當時的XML知識還僅限在怎么編寫XML實 例文檔,使用簡單的XPath對XML文檔進行搜索,而對于XML模式、XLST沒有任何概念。一句話就是XML的相關知識還是相當?shù)膮T乏,所以下決心開 始學習XML比較深入的知識,而此次的XML學習之旅將從XML模式開始。并將此學習過程中的一些心得總結出來,以供大家分享。文中有不當之處,望前輩指 點一二:)
一、XML中命名空間的作用
之前每當自己編寫XML實例文檔時總是會被命名空間所困擾,不明白它的意義和作用,但是好像 對自己編寫XML實例文檔也沒有什么影響,所以也沒有深入的去理解它。其實XML里的命名空間的作用與其它語言(如C#)中命名空間的作用差不多:為命名 提供一個容器,只要在該容器中沒有相同的命名就可以避免命名沖突。在不同的命名空間里的相同的命名會被解析成兩個不同的命名。下面的示例中定義了兩個 XML模式和一個XML實例文檔
n1schema.xsd
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="n1schema"
targetNamespace="http://tempuri.org/n1schema.xsd"
elementFormDefault="qualified"
xmlns="http://tempuri.org/n1schema.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
<xs:complexType name="Address">
<xs:sequence>
<xs:element name="Country" type="xs:string"></xs:element>
<xs:element name="Province" type="xs:string"></xs:element>
<xs:element name="City" type="xs:string"></xs:element>
</xs:sequence>
</xs:complexType>
</xs:schema>
n2schema.xsd
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="n2schema"
targetNamespace="http://tempuri.org/n2schema.xsd"
elementFormDefault="qualified"
xmlns="http://tempuri.org/n2schema.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
<xs:complexType name="Address">
<xs:sequence>
<xs:element name="Country" type="xs:string"></xs:element>
<xs:element name="State" type="xs:string"></xs:element>
<xs:element name="City" type="xs:string"></xs:element>
</xs:sequence>
</xs:complexType>
</xs:schema>
multiNamespaceTest.xml
<?xml version="1.0" encoding="utf-8" ?>
<root xmlns:n1="http://tempuri.org/n1schema.xsd"
xmlns:n2="http://tempuri.org/n2schema.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<billTo xsi:type="n1:Address">
<n1:Country>China</n1:Country>
<n1:Province>Jiangsu</n1:Province>
<n1:City>Nanjing</n1:City>
</billTo>
<shipTo xsi:type="n2:Address">
<n2:Country>USA</n2:Country>
<n2:State>IL</n2:State>
<n2:City>Chicago</n2:City>
</shipTo>
</root>
在n1shema.xsd和n2schema.xsd中都定義了一個復雜類型 Address,然后在multiNamespaceTest.xml實例文檔中引入前兩個XML模式定義的命名空間,我們可以看到billTo元素定義 為n1schema.xsd中定義的Address類型,而shipTo元素定義為n2schema.xsd中定義的Address類型,在 multiNamespaceTest.xml中這兩個Address類型并不會相互沖突。
二、XML模式創(chuàng)建的命名空間
從上面的n1schema.xsd和n2schema.xsd中可以看出,它們的schema元素都定義了targetNamespace屬性(參考W3C描述),該屬性就定義了該XML模式所創(chuàng)建的命名空間,所有在該XML模式中聲明的元素和定義的類型、屬性都處于該命名空間內(nèi),這樣在引用該命名空間的XML文檔就可以引用那些元素和類型、屬性了。
n1shema.xsd和n2schema.xsd的根元素xs:schema還可以定義elementFormDefault和attributeFormDefault屬性(參考W3C描述), 它們的值只能是qualified或unqualified,它們的默認值都是unqualified。elementFormDefault屬性用于設 定該XML模式創(chuàng)建的命名空間中的局部元素和類型被引用時是否需要指定的前綴;attributeFormDefault屬性用于設定該XML模式創(chuàng)建的 命名空間中的屬性被引用時是否需要指定的前綴。
qualifiedSchema.xsd——兩個屬性都設為qualified
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="qualifiedSchema"
targetNamespace="http://tempuri.org/qualifiedSchema.xsd"
elementFormDefault="qualified" attributeFormDefault="qualified"
xmlns="http://tempuri.org/qualifiedSchema.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
<xs:element name="books" type="BooksType"></xs:element>
<xs:complexType name="BooksType">
<xs:sequence>
<xs:element name="book" type="BookType" minOccurs="1" maxOccurs="unbounded"></xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="BookType">
<xs:sequence>
<xs:element name="ISBN" type="xs:string"></xs:element>
<xs:element name="Name" type="xs:string"></xs:element>
</xs:sequence>
<xs:attribute name="Category" type="xs:string"></xs:attribute>
</xs:complexType>
</xs:schema>
qualifiedTest.xml
<?xml version="1.0" encoding="utf-8" ?>
<q:books xmlns:q="http://tempuri.org/qualifiedSchema.xsd">
<q:book q:Category="Computer">
<q:ISBN>7115134162</q:ISBN>
<q:Name>C++ Primer Plus(第五版)</q:Name>
</q:book>
<q:book q:Category="Computer">
<q:ISBN>7115134162</q:ISBN>
<q:Name>C++ Primer Plus(第五版)</q:Name>
</q:book>
</q:books>
由上可以看到qualifiedTest.xml中引用qualifiedSchema.xsd中定義的屬性和元素時都加上了q:前綴。而下面的兩段代碼顯示了elementFormDefault和attributeFormDefault屬性設為unqualified的情形
unqualifiedSchema.xsd——兩個屬性都是用默認值unqualified
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="unqualifiedSchema"
targetNamespace="http://tempuri.org/unqualifiedSchema.xsd"
xmlns="http://tempuri.org/unqualifiedSchema.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
<xs:element name="books" type="BooksType"></xs:element>
<xs:complexType name="BooksType">
<xs:sequence>
<xs:element name="book" type="BookType" minOccurs="1" maxOccurs="unbounded"></xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="BookType">
<xs:sequence>
<xs:element name="ISBN" type="xs:string"></xs:element>
<xs:element name="Name" type="xs:string"></xs:element>
</xs:sequence>
<xs:attribute name="Category" type="xs:string"></xs:attribute>
</xs:complexType>
</xs:schema>
unqualifiedTest.xml
<?xml version="1.0" encoding="utf-8" ?>
<q:books xmlns:q="http://tempuri.org/unqualifiedSchema.xsd">
<book Category="Computer">
<ISBN>7115134162</ISBN>
<Name>C++ Primer Plus(第五版)</Name>
</book>
<book Category="Computer">
<ISBN>7115134162</ISBN>
<Name>C++ Primer Plus(第五版)</Name>
</book>
</q:books>
但是,無論 elementFormDefault和attributeFormDefault屬性設為qualified還是unqualified,引用XML模式中定義的全局元素都必須加上q:前綴(有種情況下,引用XML模式中定義的全局元素不需要加上前綴,該情況會在第三部分進行介紹)。
當然,這里還有一種特殊的情況:XML模式的schema元素沒有定義targetNamespace屬性,那么該XML模式就不會創(chuàng)建命名空間。
三、XML模式的引用方式
引用具有命名空間的XML模式
我們在編寫XML實例文檔時,可以引用本地XML模式創(chuàng)建的命名空間,也可以引用網(wǎng)絡中可訪 問的XML模式定義的命名空間,但是它們的引用方式不一樣。前面兩部分的xml文件都是引用本地XML模式定義的命名空間。下面介紹一下如何引用網(wǎng)絡中可 訪問的XML模式創(chuàng)建的命名空間。