如何在XSD中实现PRIMARY_IP与SECONDARY_IP的全局唯一性校验?
跨PRIMARY_IP和SECONDARY_IP的全局唯一性校验方案
方案一:使用XSD 1.1的断言(推荐,原生支持)
XSD 1.1新增的xs:assert约束可以实现跨元素类型的全局校验,正好解决你的问题。直接在LIST元素级别添加断言,就能检查所有PRODUCT下的PRIMARY_IP和SECONDARY_IP值是否唯一。
示例XSD代码片段:
<xs:element name="LIST"> <xs:complexType> <xs:sequence> <xs:element name="PRODUCT" maxOccurs="unbounded"> <xs:complexType> <!-- PRODUCT原有结构:主地址二选一,备用地址可选二选一 --> <xs:choice> <xs:element name="PRIMARY_IP" type="xs:string"/> <xs:element name="PRIMARY_HOST_NAME" type="xs:string"/> </xs:choice> <xs:choice minOccurs="0"> <xs:element name="SECONDARY_IP" type="xs:string"/> <xs:element name="SECONDARY_HOST_NAME" type="xs:string"/> </xs:choice> </xs:complexType> </xs:element> </xs:sequence> <!-- 全局IP唯一性校验断言 --> <xs:assert test="count(distinct-values(PRODUCT/(PRIMARY_IP | SECONDARY_IP))) = count(PRODUCT/(PRIMARY_IP | SECONDARY_IP))" xpathDefaultNamespace="##targetNamespace"> <xs:annotation> <xs:documentation>所有PRIMARY_IP和SECONDARY_IP的值必须全局唯一</xs:documentation> </xs:annotation> </xs:assert> </xs:complexType> </xs:element>
核心逻辑:
PRODUCT/(PRIMARY_IP | SECONDARY_IP)选中所有PRODUCT节点下的两类IP元素distinct-values()对选中的IP值去重- 对比去重后的数量和原始数量,相等则说明无重复
方案二:XSD 1.0环境下用Schematron补充校验
如果你的开发环境仅支持XSD 1.0(不支持断言),可以用Schematron规则弥补XSD 1.0的功能短板。它是基于XPath的XML校验语言,专门处理这类跨元素的复杂约束。
示例Schematron规则:
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron"> <sch:pattern id="unique-ips"> <sch:rule context="/LIST"> <sch:assert test="count(distinct-values(PRODUCT/(PRIMARY_IP | SECONDARY_IP))) = count(PRODUCT/(PRIMARY_IP | SECONDARY_IP))"> 存在重复IP值:{PRODUCT/(PRIMARY_IP | SECONDARY_IP)[index-of(PRODUCT/(PRIMARY_IP | SECONDARY_IP), .)[2]]} </sch:assert> </sch:rule> </sch:pattern> </sch:schema>
使用流程:先通过XSD完成基础结构校验,再用支持Schematron的工具(比如Saxon、ISO Schematron Validator)执行上述规则做唯一性校验。
注意事项
- XSD 1.1需要对应版本的解析器支持(比如Saxon-PE/EE、Xerces2-J 2.12+)
- 用Schematron时,需确保开发流程能集成额外的校验步骤
内容的提问来源于stack exchange,提问作者Chris_a
相关产品推荐
相关产品推荐

