XML Schema 复杂元素类型详解:定义及示例解析

在XML Schema(XSD)中,复杂元素是指包含其他元素和/或属性的XML元素。复杂元素可以分为四种类型:

  1. 空元素: 仅包含其他元素和/或属性的元素。
  2. 仅包含其他元素的元素: 不包含文本内容,只包含其他子元素的元素。
  3. 仅包含文本的元素: 不包含其他子元素,只包含文本内容的元素。
  4. 既包含其他元素又包含文本的元素: 同时包含其他子元素和文本内容的元素。

以下是复杂元素的一些示例:

  • 空元素:
1<product pid="1345"/>
  • 仅包含其他元素的元素:
1<employee> 2 <firstname>John</firstname> 3 <lastname>Smith</lastname> 4</employee>
  • 仅包含文本的元素:
1<food type="dessert">Ice cream</food>
  • 既包含其他元素又包含文本的元素:
1<description> 2It happened on <date lang="norwegian">03.03.99</date> .... 3</description>

在XML Schema中,可以通过以下两种方式定义复杂元素:

  1. 使用<xs:element>元素直接声明元素,并在其中定义复杂类型。例如:
1<xs:element name="employee"> 2 <xs:complexType> 3 <xs:sequence> 4 <xs:element name="firstname" type="xs:string"/> 5 <xs:element name="lastname" type="xs:string"/> 6 </xs:sequence> 7 </xs:complexType> 8</xs:element>
  1. 使用<xs:complexType>元素定义复杂类型,然后在需要的地方引用该类型。例如:
1<xs:element name="employee" type="personinfo"/> 2 3<xs:complexType name="personinfo"> 4 <xs:sequence> 5 <xs:element name="firstname" type="xs:string"/> 6 <xs:element name="lastname" type="xs:string"/> 7 </xs:sequence> 8</xs:complexType>

您还可以基于现有的复杂类型创建新的复杂类型,并在其中添加额外的元素,如上面的第二个示例所示。

1<xs:element name="employee" type="fullpersoninfo"/> 2 3<xs:complexType name="personinfo"> 4 <xs:sequence> 5 <xs:element name="firstname" type="xs:string"/> 6 <xs:element name="lastname" type="xs:string"/> 7 </xs:sequence> 8</xs:complexType> 9 10<xs:complexType name="fullpersoninfo"> 11 <xs:complexContent> 12 <xs:extension base="personinfo"> 13 <xs:sequence> 14 <xs:element name="address" type="xs:string"/> 15 <xs:element name="city" type="xs:string"/> 16 <xs:element name="country" type="xs:string"/> 17 </xs:sequence> 18 </xs:extension> 19 </xs:complexContent> 20</xs:complexType>

一个空的复杂元素在XML中不包含内容,只能包含属性。以下是关于XSD中空元素的一些说明和示例:

复杂空元素

一个空的XML元素示例:

1<product prodid="1345" />

在上面的示例中,"product"元素没有任何内容,只有一个名为"prodid"的属性。

在XSD中定义一个空元素需要遵循以下步骤:

  1. 使用<xs:element>元素定义元素。
  2. 使用<xs:complexType>元素定义复杂类型。
  3. 使用<xs:complexContent>元素指定内容模型。
  4. 使用<xs:restriction>元素基于基本类型(如整数)定义限制。
  5. 使用<xs:attribute>元素定义属性。

以下是一个定义空元素的XSD示例:

1<xs:element name="product"> 2 <xs:complexType> 3 <xs:complexContent> 4 <xs:restriction base="xs:integer"> 5 <xs:attribute name="prodid" type="xs:positiveInteger"/> 6 </xs:restriction> 7 </xs:complexContent> 8 </xs:complexType> 9</xs:element>

但是,您也可以更简洁地定义空元素,如下所示:

1<xs:element name="product"> 2 <xs:complexType> 3 <xs:attribute name="prodid" type="xs:positiveInteger"/> 4 </xs:complexType> 5</xs:element>

或者,您可以给复杂类型指定一个名称,并将"type"属性设置为该名称,如下所示:

1<xs:element name="product" type="prodtype"/> 2 3<xs:complexType name="prodtype"> 4 <xs:attribute name="prodid" type="xs:positiveInteger"/> 5</xs:complexType>

仅包含元素的复杂类型

一个"仅包含元素"的复杂类型包含一个只包含其他元素的元素。

例如,以下是一个包含仅包含其他元素的XML元素 "person" 的示例:

1<person> 2 <firstname>John</firstname> 3 <lastname>Smith</lastname> 4</person>

您可以使用<xs:sequence>元素在模式中定义 "person" 元素,如下所示:

1<xs:element name="person"> 2 <xs:complexType> 3 <xs:sequence> 4 <xs:element name="firstname" type="xs:string"/> 5 <xs:element name="lastname" type="xs:string"/> 6 </xs:sequence> 7 </xs:complexType> 8</xs:element>

在上述示例中,<xs:sequence>元素表示在 "person" 元素内部定义的元素("firstname" 和 "lastname")必须按照该顺序出现。

或者,您也可以给复杂类型指定一个名称,并将"type"属性设置为该名称,如下所示:

1<xs:element name="person" type="persontype"/> 2 3<xs:complexType name="persontype"> 4 <xs:sequence> 5 <xs:element name="firstname" type="xs:string"/> 6 <xs:element name="lastname" type="xs:string"/> 7 </xs:sequence> 8</xs:complexType>

在上述示例中,我们将复杂类型的名称设置为"persontype",然后将"type"属性设置为该名称,以便多个元素可以引用相同的复杂类型。

注意:为了允许字符数据出现在 "letter" 的子元素之间,必须将 mixed 属性设置为 "true"。<xs:sequence> 标签表示定义的元素(name、orderid 和 shipdate)必须以该顺序出现在 "letter" 元素内

我们还可以给 complexType 元素一个名称,并让 "letter" 元素具有指向 complexType 名称的 type 属性(如果使用此方法,多个元素可以引用相同的复杂类型):

1<xs:element name="letter" type="lettertype"/> 2 3<xs:complexType name="lettertype" mixed="true"> 4 <xs:sequence> 5 <xs:element name="name" type="xs:string"/> 6 <xs:element name="orderid" type="xs:positiveInteger"/> 7 <xs:element name="shipdate" type="xs:date"/> 8 </xs:sequence> 9</xs:complexType>

XSD 指示器 我们可以使用指示器来控制文档中元素的使用方式。

指示器 有七个指示器:

顺序指示器:

  • All
  • Choice
  • Sequence

出现指示器:

  • maxOccurs
  • minOccurs

组指示器:

  • 组名称
  • 属性组名称

顺序指示器 顺序指示器用于定义元素的顺序。

All 指示器 <all> 指示器指定子元素可以以任何顺序出现,并且每个子元素只能出现一次:

1<xs:element name="person"> 2 <xs:complexType> 3 <xs:all> 4 <xs:element name="firstname" type="xs:string"/> 5 <xs:element name="lastname" type="xs:string"/> 6 </xs:all> 7 </xs:complexType> 8</xs:element>

注意:在使用 <all> 指示器时,您可以将 <minOccurs> 指示器设置为 0 或 1,并且 <maxOccurs> 指示器只能设置为 1(有关 <minOccurs><maxOccurs> 的说明稍后描述)。

Choice 指示器 <choice> 指示器指定可以出现一个子元素或另一个子元素:

1<xs:element name="person"> 2 <xs:complexType> 3 <xs:choice> 4 <xs:element name="employee" type="employee"/> 5 <xs:element name="member" type="member"/> 6 </xs:choice> 7 </xs:complexType> 8</xs:element>

Sequence 指示器 <sequence> 指示器指定子元素必须以特定顺序出现:

1<xs:element name="person"> 2 <xs:complexType> 3 <xs:sequence> 4 <xs:element name="firstname" type="xs:string"/> 5 <xs:element name="lastname" type="xs:string"/> 6 </xs:sequence> 7 </xs:complexType> 8</xs:element>

出现指示器 出现指示器用于定义元素可以出现的次数。

注意:对于所有的 "顺序" 和 "组" 指示器(all、choice、sequence、组名称和组引用),maxOccurs 和 minOccurs 的默认值为 1。

maxOccurs 指示器 <maxOccurs> 指示器指定元素可以出现的最大次数:

1<xs:element name="person"> 2 <xs:complexType> 3 <xs:sequence> 4 <xs:element name="full_name" type="xs:string"/> 5 <xs:element name="child_name" type="xs:string" maxOccurs="10"/> 6 </xs:sequence> 7 </xs:complexType> 8</xs:element>

上面的示例指示了在 "person" 元素中,"child_name" 元素可以出现最少一次(minOccurs 的默认值为 1),最多出现十次。

minOccurs 指示器 <minOccurs> 指示器指定元素可以出现的最小次数:

1<xs:element name="person"> 2 <xs:complexType> 3 <xs:sequence> 4 <xs:element name="full_name" type="xs:string"/> 5 <xs:element name="child_name" type="xs:string" 6 maxOccurs="10" minOccurs="0"/> 7 </xs:sequence> 8 </xs:complexType> 9</xs:element>

上面的示例指示了在 "person" 元素中,"child_name" 元素可以出现最少零次,最多出现十次。

提示:要允许元素出现无限次数,使用 maxOccurs="unbounded" 语句:

1<xs:element name="child_name" type="xs:string" maxOccurs="unbounded"/>

一个工作示例:

名为 Myfamily.xml 的 XML 文件:

1<?xml version="1.0" encoding="UTF-8"?> 2 3<persons xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4xsi:noNamespaceSchemaLocation="family.xsd"> 5 6<person> 7 <full_name>Hege Refsnes</full_name> 8 <child_name>Cecilie</child_name> 9</person> 10 11<person> 12 <full_name>Tove Refsnes</full_name> 13 <child_name>Hege</child_name> 14 <child_name>Stale</child_name> 15 <child_name>Jim</child_name> 16 <child_name>Borge</child_name> 17</person> 18 19<person> 20 <full_name>Stale Refsnes</full_name> 21</person> 22 23</persons>

上面的 XML 文件包含一个名为 "persons" 的根元素。在这个根元素内,我们定义了三个 "person" 元素。每个 "person" 元素必须包含一个 "full_name" 元素,最多可以包含五个 "child_name" 元素。

以下是模式文件 family.xsd

1<?xml version="1.0" encoding="UTF-8"?> 2<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 3elementFormDefault="qualified"> 4 5<xs:element name="persons"> 6 <xs:complexType> 7 <xs:sequence> 8 <xs:element name="person" maxOccurs="unbounded"> 9 <xs:complexType> 10 <xs:sequence> 11 <xs:element name="full_name" type="xs:string"/> 12 <xs:element name="child_name" type="xs:string" 13 minOccurs="0" maxOccurs="5"/> 14 </xs:sequence> 15 </xs:complexType> 16 </xs:element> 17 </xs:sequence> 18 </xs:complexType> 19</xs:element> 20 21</xs:schema>

组指示器 组指示器用于定义相关的元素集合。

元素组 元素组使用 group 声明来定义,如下所示:

1<xs:group name="groupname"> 2... 3</xs:group>

您必须在组声明中定义 all、choice 或 sequence 元素。以下示例定义了一个名为 "persongroup" 的组,该组定义了必须以精确顺序出现的一组元素:

1<xs:group name="persongroup"> 2 <xs:sequence> 3 <xs:element name="firstname" type="xs:string"/> 4 <xs:element name="lastname" type="xs:string"/> 5 <xs:element name="birthday" type="xs:date"/> 6 </xs:sequence> 7</xs:group>

在定义了组之后,您可以在另一个定义中引用它,如下所示:

1<xs:group name="persongroup"> 2 <xs:sequence> 3 <xs:element name="firstname" type="xs:string"/> 4 <xs:element name="lastname" type="xs:string"/> 5 <xs:element name="birthday" type="xs:date"/> 6 </xs:sequence> 7</xs:group> 8 9<xs:element name="person" type="personinfo"/> 10 11<xs:complexType name="personinfo"> 12 <xs:sequence> 13 <xs:group ref="persongroup"/> 14 <xs:element name="country" type="xs:string"/> 15 </xs:sequence> 16</xs:complexType>

属性组

属性组使用 attributeGroup 声明来定义,如下所示:

1<xs:attributeGroup name="groupname"> 2... 3</xs:attributeGroup>

以下示例定义了一个名为 "personattrgroup" 的属性组:

1<xs:attributeGroup name="personattrgroup"> 2 <xs:attribute name="firstname" type="xs:string"/> 3 <xs:attribute name="lastname" type="xs:string"/> 4 <xs:attribute name="birthday" type="xs:date"/> 5</xs:attributeGroup>

在定义了属性组之后,您可以在另一个定义中引用它,如下所示:

1<xs:attributeGroup name="personattrgroup"> 2 <xs:attribute name="firstname" type="xs:string"/> 3 <xs:attribute name="lastname" type="xs:string"/> 4 <xs:attribute name="birthday" type="xs:date"/> 5</xs:attributeGroup> 6 7<xs:element name="person"> 8 <xs:complexType> 9 <xs:attributeGroup ref="personattrgroup"/> 10 </xs:complexType> 11</xs:element>
1<?xml version="1.0" encoding="UTF-8"?> 2 3<person> 4 <firstname>Hege</firstname> 5 <lastname>Refsnes</lastname> 6 <children> 7 <childname>Cecilie</childname> 8 </children> 9</person> 10 11<person> 12 <firstname>Stale</firstname> 13 <lastname>Refsnes</lastname> 14</person>

上述 XML 文件是有效的,因为模式 family.xsd 允许我们在 lastname 元素后面添加一个可选元素。

<any><anyAttribute> 元素用于创建可扩展文档!它们允许文档包含未在主 XML 模式中声明的附加元素。

1<xs:element name="name" type="xs:string"/> 2<xs:element name="navn" substitutionGroup="name"/> 3 4<xs:complexType name="custinfo"> 5 <xs:sequence> 6 <xs:element ref="name"/> 7 </xs:sequence> 8</xs:complexType> 9 10<xs:element name="customer" type="custinfo"/> 11<xs:element name="kunde" substitutionGroup="customer"/>

根据上述模式,一个有效的 XML 文档可能如下所示:

1<customer> 2 <name>John Smith</name> 3</customer>

或者像这样

1<kunde> 2 <navn>John Smith</navn> 3</kunde>

阻止元素替代

要防止其他元素替代指定元素,使用 block 属性:

1<xs:element name="name" type="xs:string" block="substitution"/>

看看这个 XML 模式的片段:

1<xs:element name="name" type="xs:string" block="substitution"/> 2<xs:element name="navn" substitutionGroup="name"/> 3 4<xs:complexType name="custinfo"> 5 <xs:sequence> 6 <xs:element ref="name"/> 7 </xs:sequence> 8</xs:complexType> 9 10<xs:element name="customer" type="custinfo" block="substitution"/> 11<xs:element name="kunde" substitutionGroup="customer"/>

根据上述模式,一个有效的 XML 文档看起来像这样:

1<customer> 2 <name>John Smith</name> 3</customer>

但以下不再有效:

1<kunde> 2 <navn>John Smith</navn> 3</kunde>

使用 substitutionGroup

可替代元素的类型必须与头元素的类型相同,或者派生自头元素的类型。如果可替代元素的类型与头元素的类型相同,则无需指定可替代元素的类型。

请注意,替代组中的所有元素(头元素和可替代元素)必须声明为全局元素,否则将无法正常工作!

什么是全局元素

全局元素是直接作为 "schema" 元素的子元素的元素!局部元素是嵌套在其他元素中的元素。

最后

为了方便其他设备和平台的小伙伴观看往期文章:

微信公众号搜索:Let us Coding,关注后即可获取最新文章推送

看完如果觉得有帮助,欢迎点赞、收藏、关注

点赞
收藏

评论区

加载中...

相关推荐

小记面试题-2021

CSS类1.解释浮动及其工作原理浮动的元素可以向左或者向右移动,直到它的外边缘碰到包含元素(父元素)或另一个浮动元素的边框为止。要想使元素浮动,必须为元素设置一个宽度。虽然浮动的元素已不在文档流中,但是它浮动后所处的位置依然在浮动之前的水平方向上。因为浮动元素不在文档流中,所以文档流中的块元素表现的就像浮动元素不存在一样,下面的元素会填补原来的位置。有些

总结前端元素的各种高度(上)

HTMLElement.clientHeight只读属性Element.clientHeight对于没有定义CSS或者内联布局盒子的元素为0;否则,它是元素内部的高度(以像素为单位),包含内边距,但不包括边框、外边距和水平

浅谈BFC格局~

1.BFC含义💳BFC全称:BlockFormattingContexts块级元素格式化上下文W3CCSS2.1规范中的一个概念,它是一个独立容器,决定了块级元素如何对它的内容进行布局,以及与其他元素的关系和相互关系一个页面是由很多个Box组成的,元素的类型和display属性,决定了这个Box的类型,不同类型的Box,会参与不

JavaScript用Element Traversal新属性遍历子元素

之前遍历子元素可以用childNodes属性或者firstChild进行遍历,但是要判断子元素是否是ELement元素。后来W3C通过ElementTraversal规定定义了一组新的属性来进行遍历,就不用判断了,非常方便。childNodes属性遍历遍历子元素通常是通过childNodes属性进行遍历,但是这个属性会包含空白节点,如果只是要遍历Elem

JQ选择器

如果你想寻找id以“sub\_”开头的元素,你可以使用:$("id^'sub_'")如果你想寻找id以“trim”结尾的元素,你可以使用:$("id$'trim'")要获得id包含“AAA”的元素,需要使用(这比遍历要快)$("id'trim'")可以指定元素类型input或者其他标签

JavaScript中判断数组是否包含某个元素

javascript的Array没有contains方法,有时候这会不方便,contains方法实现很简单可以扩展Array类,如下:写法1.Array.prototype.containsfunction(obj){varithis.length;while(i){