XSD复杂类型用于描述包含多个元素、属性或混合内容的结构化数据,通过<xs:complexType>定义,可包含序列(sequence)、选择(choice)、全部(all)等内容模型,并支持属性、简单内容扩展及属性组复用,与仅表示原子值的简单类型相比,复杂类型能表达更丰富的数据结构和语义关系。

XSD中复杂类型的定义,说白了,就是为了描述那些不仅仅是一个简单值,而是由多个元素、属性或甚至混合内容组成的数据结构。它允许我们将数据组织成有意义的层级和关系,就像我们构建一个乐高模型,每一块砖头(简单类型)可以单独存在,但复杂类型则是将这些砖头巧妙地组合起来,形成一个完整的作品。
要定义一个XSD复杂类型,我们主要使用
<xs:complexType>
最基本的形式,一个复杂类型可以什么都不包含,表示一个空元素:
<xs:complexType name="EmptyType"/>
或者,它可能只包含属性,没有子元素:
<xs:complexType name="ProductAttributeType"> <xs:attribute name="id" type="xs:string" use="required"/> <xs:attribute name="name" type="xs:string"/> </xs:complexType>
更多时候,复杂类型会包含子元素。这时,我们需要定义这些子元素的出现顺序、数量和类型。主要有三种内容模型(Content Model)来组织子元素:
<xs:sequence>
<xs:complexType name="AddressType">
<xs:sequence>
<xs:element name="Street" type="xs:string"/>
<xs:element name="City" type="xs:string"/>
<xs:element name="ZipCode" type="xs:string" minOccurs="0"/> <!-- 可选 -->
</xs:sequence>
<xs:attribute name="type" type="xs:string" use="optional"/>
</xs:complexType><xs:choice>
<xs:complexType name="ContactInfoType">
<xs:choice>
<xs:element name="Email" type="xs:string"/>
<xs:element name="Phone" type="xs:string"/>
</xs:choice>
</xs:complexType><xs:all>
maxOccurs
<xs:complexType name="PersonDetailsType">
<xs:all>
<xs:element name="FirstName" type="xs:string"/>
<xs:element name="LastName" type="xs:string"/>
<xs:element name="Age" type="xs:integer" minOccurs="0"/>
</xs:all>
</xs:complexType>除了这些,复杂类型还可以包含简单内容(即元素本身有一个文本值,但同时有属性),这通常通过扩展或限制一个简单类型来实现,并添加属性。
<xs:complexType name="PriceType">
<xs:simpleContent>
<xs:extension base="xs:decimal">
<xs:attribute name="currency" type="xs:string" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>这种定义方式,让
Price
<Price currency="USD">19.99</Price>
这可能是初学者最常问的问题之一。在我看来,区分复杂类型和简单类型,核心在于它们能否承载“结构”和“上下文”。
简单类型,顾名思义,它只代表一个原子值。想象一下,一个字符串、一个整数、一个日期,这些都是单一、不可再分的语义单元。它们不能拥有子元素,也不能携带属性。比如,你定义一个
xs:string
复杂类型就完全不同了。它是一个容器,一个骨架,可以容纳更多的信息。它能包含子元素,形成层级结构;它能拥有属性,为自身添加元数据或修饰符。例如,一个“地址”简单类型可能只是“北京市朝阳区”,但一个“地址”复杂类型就能分解成
Street
City
ZipCode
type
说白了,简单类型回答“是什么”,复杂类型则回答“由什么构成”以及“有什么特性”。如果你的数据需要内部结构或者需要携带额外信息(属性),那几乎可以肯定你需要复杂类型。如果只是一个纯粹的值,那么简单类型就足够了,而且更简洁。过度使用复杂类型来表示简单值,反而会增加XML的冗余和解析的复杂性。
在实际的XML Schema设计中,我们很少会遇到一个复杂类型的内容模型仅仅是单一的
sequence
choice
all
最常见的做法是,在一个
<xs:sequence>
<xs:sequence>
<xs:choice>
<xs:all>
例如,一个订单项(OrderItem)可能包含一个产品信息(ProductInfo),以及一个可选的折扣信息(DiscountInfo),而产品信息本身又可能包含一个产品ID和一个产品名称,或者一个产品SKU。
<xs:complexType name="OrderItemType">
<xs:sequence>
<!-- 产品信息,这里用一个choice来表示可以是ID+Name,也可以是SKU -->
<xs:element name="ProductInfo">
<xs:complexType>
<xs:choice>
<xs:sequence>
<xs:element name="ProductId" type="xs:string"/>
<xs:element name="ProductName" type="xs:string"/>
</xs:sequence>
<xs:element name="ProductSKU" type="xs:string"/>
</xs:choice>
</xs:complexType>
</xs:element>
<xs:element name="Quantity" type="xs:positiveInteger"/>
<xs:element name="UnitPrice" type="xs:decimal"/>
<!-- 可选的折扣信息,又是一个sequence -->
<xs:element name="Discount" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="Amount" type="xs:decimal"/>
<xs:element name="Reason" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>这里我们看到,
OrderItemType
sequence
sequence
ProductInfo
choice
choice
sequence
ProductSKU
需要注意的是,
<xs:all>
sequence
choice
element
all
xs:element
minOccurs
maxOccurs
属性在复杂类型中扮演着为元素提供元数据或修饰符的角色。它们通常用来描述元素的特性,而不是元素的核心内容。除了基本的
name
type
use
use="required"
use="optional"
use
optional
use="prohibited"
default
fixed
default="value"
fixed="value"
<xs:attribute name="status" type="xs:string" default="active"/> <xs:attribute name="version" type="xs:string" fixed="1.0"/>
属性组(xs:attributeGroup
<xs:attributeGroup name="CommonAuditAttributes"> <xs:attribute name="createdBy" type="xs:string"/> <xs:attribute name="createdDate" type="xs:dateTime"/> </xs:attributeGroup> <xs:complexType name="DocumentType"> <xs:sequence>...</xs:sequence> <xs:attributeGroup ref="CommonAuditAttributes"/> </xs:complexType>
在我看来,
attributeGroup
group
属性的类型:引用简单类型 属性的类型通常是简单类型,可以是内置的
xs:string
xs:integer
何时使用属性,何时使用子元素? 这是一个经典的XML设计哲学问题,坦白说,没有绝对的答案,但有一些经验法则:
id
type
unit
currency
Product
name
Product
status
active
inactive
在设计Schema时,对属性的这些高级用法和设计哲学有所了解,能帮助我们构建出既严谨又灵活的XML数据模型。
以上就是XSD复杂类型如何定义?的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号