寻求XML Schema中<stroke>元素校验的XPath断言表达式解决方案
针对存在性的XPath断言方案
以下是对应需求的XSD断言实现,每个约束对应独立的断言逻辑,可嵌入到对应的元素定义中:
1. 每个的异或约束(自身含 或 父含,二选一)
在<instruction>元素的定义中添加断言:
test="(exists(stroke) and not(exists(parent::repetition/stroke))) or (not(exists(stroke)) and exists(parent::repetition/stroke))"
逻辑说明:严格异或,确保两种情况仅满足其一。
2. 直接在下的必须含
在<program>元素的定义中添加断言:
test="every $i in instruction satisfies exists($i/stroke)"
逻辑说明:遍历所有直接子节点<instruction>,强制每个都包含<stroke>。
3. 含的,所有后代不能有
在<repetition>元素的定义中添加断言:
test="if (exists(stroke)) then not(exists(descendant::stroke)) else true()"
逻辑说明:当自身包含<stroke>时,检查所有后代节点中不存在任何<stroke>;否则不做限制。
4. 不含的,其直接子必须含
在<repetition>元素的定义中添加断言:
test="if (not(exists(stroke))) then every $i in instruction satisfies exists($i/stroke) else true()"
逻辑说明:自身无<stroke>时,强制所有直接子<instruction>都包含<stroke>;否则不做限制。
5. 不含的,其子可不含(异或传递)
该约束已被前面的规则覆盖:当父<repetition>不含<stroke>时,子<repetition>的行为由自身的断言(规则3、4)控制——子<repetition>可以选择不含<stroke>(此时它的子<instruction>必须含<stroke>),或者含<stroke>(此时它的所有后代不能有<stroke>),天然满足异或的传递逻辑,无需额外添加断言。
整合后的元素定义示例
以<repetition>为例,整合断言后的XSD片段:
<xs:element name="repetition"> <xs:complexType> <xs:sequence> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element ref="instruction"/> <xs:element ref="repetition"/> </xs:choice> <xs:element name="stroke" minOccurs="0"/> </xs:sequence> <xs:assert test="if (exists(stroke)) then not(exists(descendant::stroke)) else true()"/> <xs:assert test="if (not(exists(stroke))) then every $i in instruction satisfies exists($i/stroke) else true()"/> </xs:complexType> </xs:element>
<instruction>的XSD片段:
<xs:element name="instruction"> <xs:complexType> <xs:sequence> <xs:element name="stroke" minOccurs="0"/> <!-- 其他子元素 --> </xs:sequence> <xs:assert test="(exists(stroke) and not(exists(parent::repetition/stroke))) or (not(exists(stroke)) and exists(parent::repetition/stroke))"/> </xs:complexType> </xs:element>
<program>的XSD片段:
<xs:element name="program"> <xs:complexType> <xs:sequence> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element ref="instruction"/> <xs:element ref="repetition"/> </xs:choice> </xs:sequence> <xs:assert test="every $i in instruction satisfies exists($i/stroke)"/> </xs:complexType> </xs:element>
这些断言可精准区分节点层级和后代类型,覆盖所有约束条件,你可以结合测试场景逐一验证每个规则的有效性。
内容的提问来源于stack exchange,提问作者bartneck
相关产品推荐
相关产品推荐

