XML學習筆記5——XSD複雜資料類型

來源:互聯網
上載者:User

  和單一資料型別對應就是複雜資料類型了,XML元素的資料類型可以是單一資料型別,也可以是複雜資料類型,而XML屬性的資料類型就只能是單一資料型別。這篇筆記,就來學習一下XSD中的複雜資料類型了。

1、定義複雜資料類型

(1)和<simpleType>元素用來定義單一資料型別相對應,可以使用<complexType>元素來定義複雜資料類型。其文法為:

  id  name  abstract  mixed  block  final  any-attributes

其中<complexType>元素的屬性說明如下:

屬性 說明
id 唯一標識<complexType>元素本身
name 使用<complexType>元素新定義的資料類型的名稱
abstract 是否為抽象的資料類型,如為抽象的,則不能在XML文檔中直接使用這種資料類型
mixed

是否為混合類型,如果是混合類型,則允許同時出現字元資料和子項目

如果子項目是<simplexContent>,則不能使用該屬性

如果子項目是<complexContent>,則mixed屬性可以被<complexContet>元素的mixed屬性重寫

block 防止使用指定衍生類別型的複雜類型來替換當前定義的複雜類型
final 防止使用指定衍生類別型來派生新的類型
any attributes 指定non-schema命名空間的任何其他屬性

(2)複雜資料類型只能用於元素而不能用於屬性,進一步,可以根據能應用的元素對資料類型進行分類:

  • 單一資料型別:相應的元素內容是簡單類型值,並且元素不能有屬性,使用<simpleType>定義
  • 含簡單內容的複雜資料類型:相應的元素內容是簡單類型值,但元素具有屬性,使用<complexType> <simpleContent> </simpleContent> </complexType>定義,其中<simpleContent>元素的文法如下:

  • 含複雜內容的複雜資料類型:相應的元素可以是包含子項目的元素,空元素或包含混合內容的元素,而不管元素是否有屬性,使用<complexType> <complexContent> </complexContent> </complexType>定義,其中<complexContent>元素的文法如下:

(3)在根項目<schema>下定義的複雜資料類型為全域的,此時name屬性是必須的,否則為局部的。

(4)final屬性用於指定不能以那種方式派生新類型,可以取的值有#all,extension和restriction的自由組合,預設值為根項目<schema>的finalDefault屬性值。這個屬性其實和<simplexType>的final屬性類似,只是<simplexType>的final屬性取值可以是#all或restriction、list、union的自由組合。

(5)block屬性指定不能使用指定方式派生出來的類型來替換所定義的類型,可以取的值和final相同,預設值為根項目<schema>的blockDefault屬性值。

2、定義元素

(1)在定義複雜資料類型時,需要定義子項目和屬性,那麼怎麼定義元素呢?在XSD中,可以使用<element>元素來定義元素,其文法如下:

  substitutionGroup  abstract

其中element元素的各屬性如下表:

屬性 說明
id 唯一標識<element>元素
name 新定義元素的名稱,根項目<schema>下定義時為必須屬性
ref 對另一個元素的引用,可包含一個命名空間首碼
type 資料類型,可以是內建資料類型、simpleType或complexType定義的類型
substitutionGroup 可用來替代該元素的元素名稱,必須具有相同的類型或從其衍生類別型
default 預設值,元素內容是簡單類型或textOnly時使用
fixed 固定值,元素內容是簡單類型或textOnly時使用,預設值default和固定值fixed不能同時指定
form 是否通過命名空間首碼限定該元素,預設值為<schema>元素的elementFormDefault屬性值
maxOccurs 在父元素中出現的最大次數,非負整數或無限制(unbounded),預設值為1
minOccurs 在父元素中出現的最少次數,必須小於或等於maxOccurs,預設值為1
nillable 是否可以將顯示的零值分配給該元素,預設為false,如果為true,則在XML文檔中可以設定該元素的nil屬性為true
abstract 是否為抽象元素,如為抽象元素,則不能直接在XML文檔中使用
block 阻止使用指定派生方式的元素來替換當前元素
final 設定element元素上final屬性的預設值
any attributes 指定non-schema命名空間的任何其他屬性

其中父元素是根項目<schema>時,不能使用ref、form、maxOccurs、minOccurs等屬性,而substitutionGroup、final等屬性則只能使用在父元素為根項目的情況下。

(2)可以通過<group>元素將一組屬性定義在一起,然後在其它需要元素的地方用元素組的引用就可以了。文法如下:


看一個例子:

                          

這裡涉及到了三種順序指標,用於定義元素的順序:

  • all:子項目能以任意順序出現,但是每個子項目必須只出現一次,這個時候可以把minOccurs設定為0或1,並且只能把maxOccurs設定為1
  • choice:子項目是互斥的關係,只能出現其中之一
  • sequence:子項目必須按照指定的順序出現

(3)元素萬用字元

  在某些情況下,如果無法確定指定元素還需要包含哪些子項目、哪些屬性,這時候可使用萬用字元。XSD中使用<any>元素作為元素萬用字元,表示任何元素,即<any>元素出現的位置可以使用任何元素代替,其文法格式如下:


<any>元素的屬性:

屬性 說明 取值/取實值型別 預設值
id 唯一標識該元素 ID類型  
maxOccurs 該元素最多可出現的次數 非負整數或unbounded 1
minOccurs 該元素最少可出現的次數 非負整數,必須小於maxOccurs 1
namespace 指定可代替該萬用字元的元素必須來自哪個空間
  • ##any:任意命名空間的元素
  • ##other:來自當前命名空間之外的其它任意命名空間的元素
  • ##local:無命名空間限定的元素
  • ##targetNamespace:當前命名空間的元素
  • 命名空間URI:指定命名空間的元素
  • 上面多個值的列表:值列表中的任意一個命名空間的元素
 
processContents 指定應用程式或XML處理器如何對替換元素進行驗證
  • strict:XML處理器必須獲得由namespace指定的命名空間對應的Schema,並驗證來自該命名空間的所有元素
  • lax:XML處理器嘗試擷取由namespace指定的命名空間對應的Schema,成功則驗證所有元素,否則也不報錯
  • skip:XML處理器不會擷取所需命名空間,也不會進行任何驗證
strict

(4)元素替換

XSD還提供了一種機制,允許使用一個元素替換另一個元素,如果想定義某個元素可替換另一個元素,可以為該元素增加substitutionGroup屬性,其值就是該元素想替換的元素的名字。使用元素替換需注意兩點:

  • 替換元素和被替換元素必須以全域元素的形式來聲明
  • 替換元素和被替換元素要麼有相同的資料類型,要麼替換元素類型是被替換元素類型的衍生類別型

另外,

  • 可以使用final屬性來阻止自己被指定衍生類別型替換
  • 可以使用block屬性來阻止指定衍生類別型的替換

3、定義屬性

  定義屬性和定義元素是完全統一的,只是定義屬性使用<attribute>元素,其文法格式如下:

  uese

(1)<attribute>元素的屬性基本和<element>元素相同,不同的是form屬性的預設值是根項目<schema>的attributeFormDefault屬性的值。另外,use屬性是<element>所沒有的,它表示怎麼使用這個屬性,可以取的值有:

  • optional:屬性是可選的,並且可以具有指定資料類型的任意值
  • prohibited:不能使用屬性(既然不能使用,為何還要定義?主要是在派生新類型使用,用來刪除原類型的某個屬性)
  • required:必須的屬性,此時不能指定default和fixed

(2)在根項目<schema>下定義的屬性稱之為全域屬性,其它的屬性則可以通過<attribute>元素的ref屬性來引用全域屬性;也可以直接將<attribute>放在<complexType>元素內部定義屬性。

(3)類似<group>元素定義元素組,還可以使用<attributeGroup>元素定義屬性群組,其文法格式如下:


(4)屬性萬用字元

  類似於元素萬用字元,可以使用<anyAttribute>表示屬性萬用字元,其文法格式如下:


其中屬性含義與元素萬用字元<any>相同。

4、再看看怎麼派生複雜資料類型

  知道怎麼定義元素和屬性之後,就可以進一步看怎麼定義複雜資料類型了,總的來說,定義複雜資料類型需要弄清兩個問題:第一個問題是基底類型的問題——定義複雜資料類型的基礎是哪個類型?第二個問題就是派生方式的問題——派生複雜資料類型可以使用限制<restriction>和擴充<extension>兩種方式。

(1)基底類型

  • anyType類型:和DTD中的ANY類似,XSD中也有一個anyType類型,這種類型的元素沒有任何限制,可以包含子項目,可以包含字串內容,還可以添加任何屬性(但這些屬性需要在XSD檔案中定義過),anyType類型是所有簡單類型和所有複雜類型的基底類型,通常用於派生新的類型,而不是直接用來定義元素。
  • 簡單類型
  • 含簡單內容的複雜類型:元素內容是簡單類型值,但元素包括屬性
  • 空元素類型:用於定義內容為空白或Null 字元串的元素,但是該元素可以接受屬性。定義空元素類型有兩種方式:
    • 擴充長度為0的字串:如果該元素不需要包含屬性,那麼直接使用長度為0的字串類型定義該元素即可
    • 限制anyTye:限制anyType時不定義任何子項目,只定義所需屬性即可
                                                                            
  • 包含子項目的類型
  • 混合內容類型

(2)派生方式

  • 限制<restriction>
  • 擴充<extension> 

下面是我從這基底類型和派生方式兩個維度統計的一個列表:

基底類型 派生方式 定義時使用的XSD元素 說明
anyType類型 限制

<complexType><complexContent><restriction>

因為anyType只能限制,不能擴充,所以可以省略<complexContent><restriction>元素,

而直接在<complexType>內部使用<all>|<choice>|<sequence>等元素

擴充

 

anyType類型已經沒有任何限制了,所以也就不需要再擴充了

簡單類型  限制

<simpleType>

限制簡單類型最終結果也是一個簡單類型,因此使用<simpleType>元素
擴充

<complexType><simpleContent><extension>

可以通過添加屬性或屬性群組派生複雜資料類型
包含簡單內容的複雜類型  限制

<complexType><simpleContent><restriction>

  • 為元素內容增加進一步的約束
  • 為元素的屬性類型增加進一步的約束
  • 刪除某些屬性
擴充

<complexType><simpleContent><extension>

 添加屬性
空元素類型 限制

<complexType><complexContent><restriction>

  • 對指定屬性增加進一步的約束
  • 刪除某個屬性
擴充

<complexType><complexContent><extension>

  • 為原有類型增加屬性:派生出來的新類型依然是空元素類型
  • 為原有類型增加子項目:派生出來的新類型將是包含子項目的類型
  • 為原有類型增加mixed="true":派生出來的新類型將是混合內容類型
包含子項目的類型 限制 

<complexType><complexContent><restriction>

  • 可以對指定屬性的類型增加進一步約束
  • 可以對指定子項目的類型增加進一步約束
  • 可以刪除指定屬性
  • 可以刪除指定元素
擴充

<complexType><complexContent><extension>

  • 為基底類型增加新的子項目
  • 為基底類型增加新的屬性
混合內容類型 限制

<complexType><complexContent><restriction>

 限制混合內容類型的方式和限制包含子項目的類型基本相同
擴充

<complexType><complexContent><extension>

 擴充混合內容類型的方式和擴充包含子項目的類型基本相同,但是必須保留mixed="true"

  衍生類別型的另外一種用法:

  假設在XSD中定義了元素<book>,其類型是book_type(包含一個name屬性),同時還定義了book_type的派生資料類型extended_book_type(在book_type基礎上添加就價格price屬性),這種情況下,在實際XML文檔中, 可以以如下兩種方式使用<book>元素:


5、一致性約束

  定義元素還可以指定3種類型的約束:

  • key約束:相當於DB裡面的主鍵約束,要求指定內容必須存在而且唯一
  • keyref約束:相當於DB裡面的外鍵約束,要求指定內容的值必須使用refer屬性引用另一個key約束或unique約束
  • unique約束:相當於DB裡面的唯一約束,要求指定內容必須唯一,但可以不存在

這3個一致性約束都只能在<element>元素內定義,且只能在<element>元素的最後面定義。

  在DB中定義約束時,不僅需要指定使用哪類約束,還需要定義應該對哪些欄位應用約束,在XSD中定義一致性約束也完全類似,也需要指定該約束將對哪些部分起作用,因此需要在約束內使用如下兩個子項目:

  • <selector>:需指定一個xpath屬性,其值是一個XPath運算式,用來確定一個元素範圍,在一次約束定義中,<selector>必須且只能出現一次
  • <field>:需要指定一個xpath屬性,其值是一個XPath運算式,在一次約束定義中,<field>至少要出現一次,也可以出現多次

這兩個元素的含義是:在<selector>元素的XPath運算式表示的範圍內,<field>元素的XPath運算式所表示的內容必須遵守一致性約束,如果有多個<field>元素,則它們的XPath運算式內容的組合必須遵守一致性約束,當XPath運算式所表示的內容無需遵守,這個概念相當於DB中的多列組合約束。

  看下例子:

                                            

6、定義符號

最後看一下和DTD中對應的定義符號的用法,在XSD中使用<notation>元素定義符號,用來標識XML文檔中的外部資料,該元素可接受的屬性有:

  • id:指定該符號的唯一標識,通常無需指定
  • name:指定該符號的名稱,是一個必填屬性,而且該名稱在整個XSD內必須是唯一的
  • public:指定該符號所標識資料的外部格式或對應處理常式,必填屬性,相當於DTD中<!NOTATION>中PUBLIC的作用
  • system:指定該符號所標識資料的外部格式或對應處理常式,可選屬性,相當於DTD中<!NOTATION>中SYSTEM的作用

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.