如何让XSD中元素的整数范围依赖于其他元素?
问题分析与解决方案
首先明确结论:无法在不修改random类型中start和end的原有simpleType取值范围的前提下实现需求。
原因在于XSD 1.1的验证顺序:先验证属性/元素的simpleType硬限制,再执行复杂类型的xs:assert断言。当random的start取值超过9时,会被xs:maxInclusive="9"直接拦截,断言根本没有执行的机会,无法绕过这个底层限制。
正确实现方案
要兼顾绝大多数场景的取值限制和特殊场景的大值需求,需要调整random类型的simpleType,将硬限制改为断言控制:
1. 修改random类型的属性限制
移除原有最大值的硬限制,保留最小值,设置一个足够大的上限:
<xs:complexType name="random"> <xs:attribute name="start"> <xs:simpleType> <xs:restriction base="xs:integer"> <xs:minInclusive value="1"/> <!-- 设为足够大的上限,替代原有硬限制 --> <xs:maxInclusive value="1000"/> </xs:restriction> </xs:simpleType> </xs:attribute> <xs:attribute name="end"> <xs:simpleType> <xs:restriction base="xs:integer"> <xs:minInclusive value="2"/> <xs:maxInclusive value="1000"/> </xs:restriction> </xs:simpleType> </xs:attribute> <!-- 保留原有start ≤ end的基础断言 --> <xs:assert test="@start le @end"/> </xs:complexType>
2. 在annotation类型中添加场景控制断言
根据annotation元素的extended属性(匹配你示例中的bigValue场景),添加条件断言:
<xs:complexType name="annotation" mixed="true"> <xs:sequence> <xs:element name="random" type="random" minOccurs="0" maxOccurs="1"/> </xs:sequence> <!-- 补充定义你示例中用到的extended属性 --> <xs:attribute name="extended" type="xs:string"/> <xs:attribute name="annotation"> <xs:simpleType> <xs:union memberTypes="comments dice"/> </xs:simpleType> </xs:attribute> <!-- 核心断言:random存在时,要么是bigValue场景,要么遵守原有取值范围 --> <xs:assert test="not(exists(random)) or (@extended = 'bigValue') or (random/@start le 9 and random/@end le 10)"/> </xs:complexType>
你之前的断言错误说明
- XPath语法错误:比如
exists(annotation/bigValue),上下文是annotation元素,检查属性应使用@extended = 'bigValue'而非子元素路径;引用random的属性需用random/@start,而非random.start或@random.start。 - 逻辑覆盖不全:未考虑
random元素不存在的情况,导致无random时断言也触发错误。 - 硬限制无法绕过:原
random类型的xs:maxInclusive是底层验证,断言无法覆盖该规则,这是核心问题。
内容的提问来源于stack exchange,提问作者Daniel Janz
相关产品推荐
相关产品推荐

