如何实现类集合的XML序列,避免prop2标签重复且无需预定义属性?
问题:如何在不预定义元素的前提下确保XML子元素唯一性(实现集合式序列)
给定XML实例
<properties> <prop1>3.9.0</prop1> <prop2>1.2.0</prop2> <prop2>1.2.1</prop2> <prop3>6.6.0</prop3> </properties>
原XSD定义
<xs:element minOccurs="0" name="properties"> <xs:complexType> <xs:sequence> <xs:any minOccurs="0" maxOccurs="unbounded" processContents="skip"/> </xs:sequence> </xs:complexType> </xs:element>
需求说明
希望防止示例中<prop2>标签重复的情况,同时不对子元素的具体名称、内容做其他限制。核心诉求是:无需预定义任何子元素的前提下,确保所有直接子元素的名称唯一,即实现一个表现为集合的XML序列。
解决方案
关键前提
XSD 1.0无法实现这种动态的唯一性约束(因为无法引用未预定义的元素名称),必须使用XSD 1.1的断言(<xs:assert>)功能来实现。
修改后的XSD代码
<xs:element minOccurs="0" name="properties"> <xs:complexType> <xs:sequence> <xs:any minOccurs="0" maxOccurs="unbounded" processContents="skip"/> </xs:sequence> <!-- 添加断言确保子元素名称唯一 --> <xs:assert test="every $child in ./* satisfies count(./*[local-name() = local-name($child)]) = 1"/> </xs:complexType> </xs:element>
断言逻辑解释
断言中的XPath表达式every $child in ./* satisfies count(./*[local-name() = local-name($child)]) = 1的含义是:
- 遍历
<properties>下的每一个直接子元素$child - 检查当前
<properties>下,与$child本地名称(即标签名,如prop1、prop2)相同的子元素数量必须等于1 - 只要存在任意一个标签名重复的子元素,验证就会失败
效果验证
- 原XML实例中存在两个
<prop2>,用上述XSD验证会直接报错 - 所有子元素名称唯一的XML实例(如删除其中一个
<prop2>)则能通过验证 - 完全不需要预定义任何具体的子元素名称,符合需求中的无限制要求
内容的提问来源于stack exchange,提问作者caduceus
相关产品推荐
相关产品推荐

