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

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

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

  • 空元素:
<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中,可以通过以下两种方式定义复杂元素:

  1. 使用<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>
  1. 使用<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中定义一个空元素需要遵循以下步骤:

  1. 使用<xs:element>元素定义元素。
  2. 使用<xs:complexType>元素定义复杂类型。
  3. 使用<xs:complexContent>元素指定内容模型。
  4. 使用<xs:restriction>元素基于基本类型(如整数)定义限制。
  5. 使用<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,关注后即可获取最新文章推送

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

XML Schema 复杂元素类型详解:定义及示例解析的更多相关文章

  1. C++之string类型详解

    C++之string类型详解 之所以抛弃char*的字符串而选用C++标准程序库中的string类,是因为他和前者比较起来,不必担心内存是否足够.字符串长度等等,而且作为一个泛型类出现,他集成的操作函 ...

  2. Mybatis----resultMap类型详解

    Mybatis----resultMap类型详解 这篇文章主要给大家介绍了关于Mybatis中强大的resultMap功能的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Mybatis具 ...

  3. Mybatis----传入参数parameterType类型详解

    Mybatis----传入参数parameterType类型详解 前言 Mybatis的Mapper文件中的select.insert.update.delete元素中有一个parameterType ...

  4. C#进阶系列——WebApi 接口返回值不困惑:返回值类型详解

    前言:已经有一个月没写点什么了,感觉心里空落落的.今天再来篇干货,想要学习Webapi的园友们速速动起来,跟着博主一起来学习吧.之前分享过一篇 C#进阶系列——WebApi接口传参不再困惑:传参详解  ...

  5. C++11 并发指南六(atomic 类型详解四 C 风格原子操作介绍)

    前面三篇文章<C++11 并发指南六(atomic 类型详解一 atomic_flag 介绍)>.<C++11 并发指南六( <atomic> 类型详解二 std::at ...

  6. C++11 并发指南六( <atomic> 类型详解二 std::atomic )

    C++11 并发指南六(atomic 类型详解一 atomic_flag 介绍)  一文介绍了 C++11 中最简单的原子类型 std::atomic_flag,但是 std::atomic_flag ...

  7. (转)C# WebApi 接口返回值不困惑:返回值类型详解

    原文地址:http://www.cnblogs.com/landeanfen/p/5501487.html 正文 前言:已经有一个月没写点什么了,感觉心里空落落的.今天再来篇干货,想要学习Webapi ...

  8. Swift - 可选类型详解

    可选类型详解 直接上代码解释 // 类中所有的属性在对象初始化时,必须有初始化值 class Person : NSObject { var name : String? var view : UIV ...

  9. (转)MySQL字段类型详解

    MySQL字段类型详解 原文:http://www.cnblogs.com/100thMountain/p/4692842.html MySQL支持大量的列类型,它可以被分为3类:数字类型.日期和时间 ...

  10. [转]C#进阶系列——WebApi 接口返回值不困惑:返回值类型详解

    本文转自:http://www.cnblogs.com/landeanfen/p/5501487.html 阅读目录 一.void无返回值 二.IHttpActionResult 1.Json(T c ...

随机推荐

  1. Viu联合华为HMS生态,共创影音娱乐新体验

    华为HMS生态携手流媒体平台Viu,为海外消费者打造精品移动娱乐应用体验,并助力提升流量变现能力.Viu在中东非.东南亚等16个国家及地区提供广告合作和付费会员服务,支持优质视频内容高清点播和直播.自 ...

  2. 第十六篇:jQuery基础

    一.jQuery和Dom的关系 http://jquery.cuishifeng.cn/ 模块,类库 DOM/BOM/JavaScript的类库: 二.jQuery选择器 1.查找元素 DOM: 10 ...

  3. The First 寒假集训の小总结

    转眼间十五天的寒假集训已经结束,也学习到了许多新知识,dp,线段树,单调栈和单调队列......,假期过得还是很有意义的,虽然我的两次考试成绩不尽人意(只能怪我自己没有好好理解知识点还有好好做题),但 ...

  4. 基于Material Design风格开源、易用、强大的WPF UI控件库

    前言 今天大姚给大家分享一款基于Material Design风格开源.免费(MIT License).易于使用.强大的WPF UI控件库:MaterialDesignInXamlToolkit. 项 ...

  5. 基于locust全链路压测系统

    2021年中旬就计划着搭建一套压测系统,大约9月份已经搭建完成,使用至今还是比较稳定了,分享一下搭建思路及过程: 为什么选择Locust呢,因为Locust可以仅需要执行命令就可以完成压测任务,并且集 ...

  6. 安装以及破解Navicat

    1.下载Navicat软件安装包 链接:https://pan.baidu.com/s/1RltCPjg1mmpOjC7vxAjQ4g 提取码:v4k8 2.下载好文件打开是这样的,先运行 " ...

  7. 力扣166(java)-分数到小数(中等)

    题目: 给定两个整数,分别表示分数的分子 numerator 和分母 denominator,以 字符串形式返回小数 . 如果小数部分为循环小数,则将循环的部分括在括号内. 如果存在多个答案,只需返回 ...

  8. KubeDL HostNetwork:加速分布式训练通信效率

    ​简介:ubeDL 为分布式训练作业带来了 HostNetwork 网络模式,支持计算节点之间通过宿主机网络相互通信以提升网络性能,同时适应 RDMA/SCC 等新型高性能数据中心架构的网络环境,此外 ...

  9. [Mobi] 什么是手机 Root 和 Magisk、Magisk App

    手机进行 Root 操作就是让我们能够拥有超级权限,包括被手机厂商所禁止的一些操作. 传统 Root 手段会修改系统文件,因而一些安全性要求较高的 App 会禁止自己在 Root 过的手机上运行. M ...

  10. WPF 已知问题 传入错误数据给到 WriteableBitmap 可能导致渲染线程锁住

    本文记录一个 WPF 已知问题,此问题已经被我修复.传入错误的数据给到 WriteableBitmap 对象,比如调用 WritePixels 时传入错误的 stride 数值,将可能导致渲染线程进入 ...