XSD中定义抽象类型需设abstract="true",仅能被extension或restriction继承,不可直接实例化;配合substitutionGroup可实现xsi:type多态。

在XSD中定义抽象类型,核心是使用 abstract="true" 属性,并配合 extension 或 restriction 实现继承。抽象类型本身不能直接用于元素实例,只能被其他类型扩展或限制。
定义抽象复杂类型
用 <xs:complexType abstract="true"> 声明一个不可实例化的基类型:
<xs:complexType name="Person" abstract="true">
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="email" type="xs:string"/>
</xs:sequence>
</xs:complexType>
这个 Person 类型不能直接赋给某个 <xs:element> 的 type 属性,否则校验会失败。
让具体类型继承抽象类型
使用 <xs:extension base="Person"> 扩展抽象基类,添加专属字段:
<xs:complexType name="Student">
<xs:complexContent>
<xs:extension base="Person">
<xs:sequence>
<xs:element name="studentId" type="xs:integer"/>
<xs:element name="grade" type="xs:string"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="Teacher">
<xs:complexContent>
<xs:extension base="Person">
<xs:sequence>
<xs:element name="staffId" type="xs:integer"/>
<xs:element name="subject" type="xs:string"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
在元素声明中使用继承后的类型
抽象类型不能直接用,但继承后的具体类型可以:
- 用
type="Student"声明学生元素:<xs:element name="student" type="Student"/> - 用
type="Teacher"声明教师元素:<xs:element name="teacher" type="Teacher"/> - 若需支持多态(如一个
person元素可接受 Student 或 Teacher),可配合xsi:type使用,前提是元素声明使用抽象类型名 +substitutionGroup或abstract="true"配合<xs:element>的abstract属性
可选:定义抽象元素(支持多态替换)
如果希望 XML 中能用 <person xsi:type="Student"> 这种方式,还需定义抽象元素并设置替代组:
<xs:element name="person" type="Person" abstract="true"/> <xs:element name="student" type="Student" substitutionGroup="person"/> <xs:element name="teacher" type="Teacher" substitutionGroup="person"/>
这样 XML 中就可以写:
<person xsi:type="student"> <name>Alice</name> <email>a@example.com</email> <studentId>1001</studentId> <grade>A</grade> </person>
只要引用了 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance",校验器就能根据 xsi:type 正确识别实际类型。
基本上就这些。抽象类型 + extension + substitutionGroup 是 XSD 实现“面向对象式”建模的关键组合,不复杂但容易忽略 abstract 和 substitutionGroup 的配合。










