构建含未知名称复杂类型的XML Schema实现方案咨询
解决方案:构建符合需求的XML Schema
没问题,我来帮你搞定这个Schema的构建。你的核心需求是:固定<general>和<files>的层级结构,同时允许<files>下出现任意数量、任意名称的子元素,但这些子元素必须严格遵循包含<sum>→<count>的结构。下面分两种主流XSD版本给出方案:
推荐方案:XSD 1.1(支持任意名称元素的严格验证)
XSD 1.1引入了通配符元素名的支持(name="*"),可以完美匹配你的需求——不需要提前定义所有可能的元素名,就能强制验证它们的内部结构。
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" vc:minVersion="1.1"> <!-- 定义<count>为整数类型 --> <xs:element name="count" type="xs:int"/> <!-- 定义<sum>的结构:必须包含<count> --> <xs:complexType name="SumType"> <xs:sequence> <xs:element ref="count"/> </xs:sequence> </xs:complexType> <xs:element name="sum" type="SumType"/> <!-- 定义任意名称元素的通用结构:必须包含<sum> --> <xs:complexType name="ArbitraryNamedElementType"> <xs:sequence> <xs:element ref="sum"/> </xs:sequence> </xs:complexType> <!-- 定义<files>:允许任意数量的任意名称元素,且必须符合通用结构 --> <xs:complexType name="FilesType"> <xs:sequence> <xs:element name="*" type="ArbitraryNamedElementType" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> <xs:element name="files" type="FilesType"/> <!-- 根元素<general>:必须包含<files> --> <xs:complexType name="GeneralType"> <xs:sequence> <xs:element ref="files"/> </xs:sequence> </xs:complexType> <xs:element name="general" type="GeneralType"/> </xs:schema>
方案说明
- 用
xs:element name="*"匹配<files>下所有任意名称的元素 - 强制要求这些元素必须符合
ArbitraryNamedElementType类型(即包含<sum>,而<sum>又必须包含整数类型的<count>) - 完全支持任意数量的这类元素(
maxOccurs="unbounded")
兼容方案:XSD 1.0(适配旧版工具)
如果你的开发环境只支持XSD 1.0,有两种选择:
选项1:预定义元素名的严格验证
通过**替换组(substitution group)**实现,需要提前定义所有可能出现的元素名(比如something、something_else):
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"> <!-- 定义<count>为整数类型 --> <xs:element name="count" type="xs:int"/> <!-- 定义<sum>的结构 --> <xs:complexType name="SumType"> <xs:sequence> <xs:element ref="count"/> </xs:sequence> </xs:complexType> <xs:element name="sum" type="SumType"/> <!-- 定义抽象基元素,所有自定义名称元素都替换它 --> <xs:element name="baseNamedElement" abstract="true"> <xs:complexType> <xs:sequence> <xs:element ref="sum"/> </xs:sequence> </xs:complexType> </xs:element> <!-- 预定义允许的元素名,加入替换组 --> <xs:element name="something" substitutionGroup="baseNamedElement"/> <xs:element name="something_else" substitutionGroup="baseNamedElement"/> <!-- 可以继续添加更多元素,比如<another_item>等 --> <!-- 定义<files>:允许任意数量的基元素替换项 --> <xs:complexType name="FilesType"> <xs:sequence> <xs:element ref="baseNamedElement" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> <xs:element name="files" type="FilesType"/> <!-- 根元素<general> --> <xs:complexType name="GeneralType"> <xs:sequence> <xs:element ref="files"/> </xs:sequence> </xs:complexType> <xs:element name="general" type="GeneralType"/> </xs:schema>
选项2:完全任意元素的宽松验证
如果元素名完全不可预知,XSD 1.0无法做到严格强制验证,但可以用xs:any实现宽松验证——即如果元素包含<sum>和<count>,则验证它们的结构,否则不做强制要求:
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"> <!-- 定义<count>为整数类型 --> <xs:element name="count" type="xs:int"/> <!-- 定义<sum>的结构 --> <xs:complexType name="SumType"> <xs:sequence> <xs:element ref="count"/> </xs:sequence> </xs:complexType> <xs:element name="sum" type="SumType"/> <!-- 定义<files>:允许任意数量的任意元素,宽松验证内部结构 --> <xs:complexType name="FilesType"> <xs:sequence> <xs:any processContents="lax" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> <xs:element name="files" type="FilesType"/> <!-- 根元素<general> --> <xs:complexType name="GeneralType"> <xs:sequence> <xs:element ref="files"/> </xs:sequence> </xs:complexType> <xs:element name="general" type="GeneralType"/> </xs:schema>
方案说明
- 选项1适合你能提前知道所有可能元素名的场景,能做到严格验证
- 选项2适合元素名完全不可控的场景,但无法强制要求每个元素都包含
<sum>结构
内容的提问来源于stack exchange,提问作者bentz123
相关产品推荐
相关产品推荐

