在XML Schema(XSD)中,複雜元素是指包含其他元素和/或屬性的XML元素。複雜元素可以分為四種型別:
- 空元素: 僅包含其他元素和/或屬性的元素。
- 僅包含其他元素的元素: 不包含文字內容,只包含其他子元素的元素。
- 僅包含文字的元素: 不包含其他子元素,只包含文字內容的元素。
- 既包含其他元素又包含文字的元素: 同時包含其他子元素和文字內容的元素。
以下是複雜元素的一些示例:
- 空元素:
<product pid="1345"/>
- 僅包含其他元素的元素:
<employee>
<firstname>John</firstname>
<lastname>Smith</lastname>
</employee>
- 僅包含文字的元素:
<food type="dessert">Ice cream</food>
- 既包含其他元素又包含文字的元素:
<description>
It happened on <date lang="norwegian">03.03.99</date> ....
</description>
在XML Schema中,可以透過以下兩種方式定義複雜元素:
- 使用
<xs:element>
元素直接宣告元素,並在其中定義複雜型別。例如:
<xs:element name="employee">
<xs:complexType>
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
- 使用
<xs:complexType>
元素定義複雜型別,然後在需要的地方引用該型別。例如:
<xs:element name="employee" type="personinfo"/>
<xs:complexType name="personinfo">
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
您還可以基於現有的複雜型別建立新的複雜型別,並在其中新增額外的元素,如上面的第二個示例所示。
<xs:element name="employee" type="fullpersoninfo"/>
<xs:complexType name="personinfo">
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="fullpersoninfo">
<xs:complexContent>
<xs:extension base="personinfo">
<xs:sequence>
<xs:element name="address" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
一個空的複雜元素在XML中不包含內容,只能包含屬性。以下是關於XSD中空元素的一些說明和示例:
複雜空元素
一個空的XML元素示例:
<product prodid="1345" />
在上面的示例中,"product"元素沒有任何內容,只有一個名為"prodid"的屬性。
在XSD中定義一個空元素需要遵循以下步驟:
- 使用
<xs:element>
元素定義元素。 - 使用
<xs:complexType>
元素定義複雜型別。 - 使用
<xs:complexContent>
元素指定內容模型。 - 使用
<xs:restriction>
元素基於基本型別(如整數)定義限制。 - 使用
<xs:attribute>
元素定義屬性。
以下是一個定義空元素的XSD示例:
<xs:element name="product">
<xs:complexType>
<xs:complexContent>
<xs:restriction base="xs:integer">
<xs:attribute name="prodid" type="xs:positiveInteger"/>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
</xs:element>
但是,您也可以更簡潔地定義空元素,如下所示:
<xs:element name="product">
<xs:complexType>
<xs:attribute name="prodid" type="xs:positiveInteger"/>
</xs:complexType>
</xs:element>
或者,您可以給複雜型別指定一個名稱,並將"type"屬性設定為該名稱,如下所示:
<xs:element name="product" type="prodtype"/>
<xs:complexType name="prodtype">
<xs:attribute name="prodid" type="xs:positiveInteger"/>
</xs:complexType>
僅包含元素的複雜型別
一個"僅包含元素"的複雜型別包含一個只包含其他元素的元素。
例如,以下是一個包含僅包含其他元素的XML元素 "person" 的示例:
<person>
<firstname>John</firstname>
<lastname>Smith</lastname>
</person>
您可以使用<xs:sequence>
元素在模式中定義 "person" 元素,如下所示:
<xs:element name="person">
<xs:complexType>
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
在上述示例中,<xs:sequence>
元素表示在 "person" 元素內部定義的元素("firstname" 和 "lastname")必須按照該順序出現。
或者,您也可以給複雜型別指定一個名稱,並將"type"屬性設定為該名稱,如下所示:
<xs:element name="person" type="persontype"/>
<xs:complexType name="persontype">
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
在上述示例中,我們將複雜型別的名稱設定為"persontype",然後將"type"屬性設定為該名稱,以便多個元素可以引用相同的複雜型別。
注意:為了允許字元資料出現在 "letter" 的子元素之間,必須將 mixed 屬性設定為 "true"。<xs:sequence>
標籤表示定義的元素(name、orderid 和 shipdate)必須以該順序出現在 "letter" 元素內
我們還可以給 complexType 元素一個名稱,並讓 "letter" 元素具有指向 complexType 名稱的 type 屬性(如果使用此方法,多個元素可以引用相同的複雜型別):
<xs:element name="letter" type="lettertype"/>
<xs:complexType name="lettertype" mixed="true">
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="orderid" type="xs:positiveInteger"/>
<xs:element name="shipdate" type="xs:date"/>
</xs:sequence>
</xs:complexType>
XSD 指示器
我們可以使用指示器來控制文件中元素的使用方式。
指示器
有七個指示器:
順序指示器:
- All
- Choice
- Sequence
出現指示器:
- maxOccurs
- minOccurs
組指示器:
- 組名稱
- 屬性組名稱
順序指示器
順序指示器用於定義元素的順序。
All 指示器
<all>
指示器指定子元素可以以任何順序出現,並且每個子元素只能出現一次:
<xs:element name="person">
<xs:complexType>
<xs:all>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:all>
</xs:complexType>
</xs:element>
注意:在使用 <all>
指示器時,您可以將 <minOccurs>
指示器設定為 0 或 1,並且 <maxOccurs>
指示器只能設定為 1(有關 <minOccurs>
和 <maxOccurs>
的說明稍後描述)。
Choice 指示器
<choice>
指示器指定可以出現一個子元素或另一個子元素:
<xs:element name="person">
<xs:complexType>
<xs:choice>
<xs:element name="employee" type="employee"/>
<xs:element name="member" type="member"/>
</xs:choice>
</xs:complexType>
</xs:element>
Sequence 指示器
<sequence>
指示器指定子元素必須以特定順序出現:
<xs:element name="person">
<xs:complexType>
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
出現指示器
出現指示器用於定義元素可以出現的次數。
注意:對於所有的 "順序" 和 "組" 指示器(all、choice、sequence、組名稱和組引用),maxOccurs 和 minOccurs 的預設值為 1。
maxOccurs 指示器
<maxOccurs>
指示器指定元素可以出現的最大次數:
<xs:element name="person">
<xs:complexType>
<xs:sequence>
<xs:element name="full_name" type="xs:string"/>
<xs:element name="child_name" type="xs:string" maxOccurs="10"/>
</xs:sequence>
</xs:complexType>
</xs:element>
上面的示例指示了在 "person" 元素中,"child_name" 元素可以出現最少一次(minOccurs 的預設值為 1),最多出現十次。
minOccurs 指示器
<minOccurs>
指示器指定元素可以出現的最小次數:
<xs:element name="person">
<xs:complexType>
<xs:sequence>
<xs:element name="full_name" type="xs:string"/>
<xs:element name="child_name" type="xs:string"
maxOccurs="10" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
上面的示例指示了在 "person" 元素中,"child_name" 元素可以出現最少零次,最多出現十次。
提示:要允許元素出現無限次數,使用 maxOccurs="unbounded" 語句:
<xs:element name="child_name" type="xs:string" maxOccurs="unbounded"/>
一個工作示例:
名為 Myfamily.xml
的 XML 檔案:
<?xml version="1.0" encoding="UTF-8"?>
<persons xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="family.xsd">
<person>
<full_name>Hege Refsnes</full_name>
<child_name>Cecilie</child_name>
</person>
<person>
<full_name>Tove Refsnes</full_name>
<child_name>Hege</child_name>
<child_name>Stale</child_name>
<child_name>Jim</child_name>
<child_name>Borge</child_name>
</person>
<person>
<full_name>Stale Refsnes</full_name>
</person>
</persons>
上面的 XML 檔案包含一個名為 "persons" 的根元素。在這個根元素內,我們定義了三個 "person" 元素。每個 "person" 元素必須包含一個 "full_name" 元素,最多可以包含五個 "child_name" 元素。
以下是模式檔案 family.xsd
:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xs:element name="persons">
<xs:complexType>
<xs:sequence>
<xs:element name="person" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="full_name" type="xs:string"/>
<xs:element name="child_name" type="xs:string"
minOccurs="0" maxOccurs="5"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
組指示器
組指示器用於定義相關的元素集合。
元素組
元素組使用 group 宣告來定義,如下所示:
<xs:group name="groupname">
...
</xs:group>
您必須在組宣告中定義 all、choice 或 sequence 元素。以下示例定義了一個名為 "persongroup" 的組,該組定義了必須以精確順序出現的一組元素:
<xs:group name="persongroup">
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
<xs:element name="birthday" type="xs:date"/>
</xs:sequence>
</xs:group>
在定義了組之後,您可以在另一個定義中引用它,如下所示:
<xs:group name="persongroup">
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
<xs:element name="birthday" type="xs:date"/>
</xs:sequence>
</xs:group>
<xs:element name="person" type="personinfo"/>
<xs:complexType name="personinfo">
<xs:sequence>
<xs:group ref="persongroup"/>
<xs:element name="country" type="xs:string"/>
</xs:sequence>
</xs:complexType>
屬性組
屬性組使用 attributeGroup 宣告來定義,如下所示:
<xs:attributeGroup name="groupname">
...
</xs:attributeGroup>
以下示例定義了一個名為 "personattrgroup" 的屬性組:
<xs:attributeGroup name="personattrgroup">
<xs:attribute name="firstname" type="xs:string"/>
<xs:attribute name="lastname" type="xs:string"/>
<xs:attribute name="birthday" type="xs:date"/>
</xs:attributeGroup>
在定義了屬性組之後,您可以在另一個定義中引用它,如下所示:
<xs:attributeGroup name="personattrgroup">
<xs:attribute name="firstname" type="xs:string"/>
<xs:attribute name="lastname" type="xs:string"/>
<xs:attribute name="birthday" type="xs:date"/>
</xs:attributeGroup>
<xs:element name="person">
<xs:complexType>
<xs:attributeGroup ref="personattrgroup"/>
</xs:complexType>
</xs:element>
<?xml version="1.0" encoding="UTF-8"?>
<person>
<firstname>Hege</firstname>
<lastname>Refsnes</lastname>
<children>
<childname>Cecilie</childname>
</children>
</person>
<person>
<firstname>Stale</firstname>
<lastname>Refsnes</lastname>
</person>
上述 XML 檔案是有效的,因為模式 family.xsd
允許我們在 lastname
元素後面新增一個可選元素。
<any>
和 <anyAttribute>
元素用於建立可擴充套件文件!它們允許文件包含未在主 XML 模式中宣告的附加元素。
<xs:element name="name" type="xs:string"/>
<xs:element name="navn" substitutionGroup="name"/>
<xs:complexType name="custinfo">
<xs:sequence>
<xs:element ref="name"/>
</xs:sequence>
</xs:complexType>
<xs:element name="customer" type="custinfo"/>
<xs:element name="kunde" substitutionGroup="customer"/>
根據上述模式,一個有效的 XML 文件可能如下所示:
<customer>
<name>John Smith</name>
</customer>
或者像這樣
<kunde>
<navn>John Smith</navn>
</kunde>
阻止元素替代
要防止其他元素替代指定元素,使用 block 屬性:
<xs:element name="name" type="xs:string" block="substitution"/>
看看這個 XML 模式的片段:
<xs:element name="name" type="xs:string" block="substitution"/>
<xs:element name="navn" substitutionGroup="name"/>
<xs:complexType name="custinfo">
<xs:sequence>
<xs:element ref="name"/>
</xs:sequence>
</xs:complexType>
<xs:element name="customer" type="custinfo" block="substitution"/>
<xs:element name="kunde" substitutionGroup="customer"/>
根據上述模式,一個有效的 XML 文件看起來像這樣:
<customer>
<name>John Smith</name>
</customer>
但以下不再有效:
<kunde>
<navn>John Smith</navn>
</kunde>
使用 substitutionGroup
可替代元素的型別必須與頭元素的型別相同,或者派生自頭元素的型別。如果可替代元素的型別與頭元素的型別相同,則無需指定可替代元素的型別。
請注意,替代組中的所有元素(頭元素和可替代元素)必須宣告為全域性元素,否則將無法正常工作!
什麼是全域性元素
全域性元素是直接作為 "schema" 元素的子元素的元素!區域性元素是巢狀在其他元素中的元素。
最後
為了方便其他裝置和平臺的小夥伴觀看往期文章:
微信公眾號搜尋:Let us Coding
,關注後即可獲取最新文章推送
看完如果覺得有幫助,歡迎點贊、收藏、關注