substitutionGroup 用于语义等价的元素替换,需先声明 abstract=”true” 的头元素(如 comment),再通过 substitutionGroup 属性将 shipComment、customerComment 等元素挂靠其下,且类型必须兼容;xml 实例中可任选替换元素替代头元素位置。

substitutionGroup 用于让一个元素“代替”另一个元素出现在 XML 文档中,核心是实现语义等价的灵活替换,不是类型继承,也不改变校验逻辑——只要被替换元素符合主元素的类型定义,就可通过校验。
必须先声明一个可被替换的“头元素”
这个头元素通常设为 abstract=”true”,表示它不能直接在 XML 中实例化,只作为占位和分组依据:
- 用
声明抽象头元素 - 它的
type定义了所有替换元素共用的数据结构(比如文本+作者) - 不加
abstract="true"也能用,但失去“禁止直接使用头元素”的约束力
替换元素通过 substitutionGroup 属性挂靠
每个想参与替换的元素,需显式声明 substitutionGroup 并指向头元素名:
- 注意:substitutionGroup 的值是 QName(无命名空间前缀时就是头元素名),不是类型名或路径
- 替换元素的
type必须与头元素兼容(相同、派生自其类型,或为xs:anyType)
XML 实例中可自由选用任一替换元素
只要 schema 中定义了 substitutionGroup 关系,XML 文档里就能用替换元素替代头元素位置:
- 假设 schema 允许
... - 实际 XML 可写成:
或... ... - 解析器和校验器会按
comment的类型(如commentType)来验证内容,不管标签名是什么
常见配合用法和注意事项
substitutionGroup 不是孤立功能,常结合其他机制增强表达力:
- 与
xsi:type联用:当替换元素类型比头元素更具体时,可在 XML 中加xsi:type="shipCommentType"显式指定派生类型 - 避免循环引用:A 的 substitutionGroup 是 B,B 的就不能反过来设为 A
- 命名空间敏感:如果头元素在目标命名空间中,替换元素的
substitutionGroup值需带前缀或按 schema 默认处理规则匹配 - 不能跨 schema 文件直接引用:头元素和替换元素一般需在同一个
内声明,或通过/正确引入