XSD Schema中XPath断言校验partNumber引用有效性问题
XSD断言修复:校验跨属性引用的partNumber有效性
原有断言的错误点
你写在schema第28、29行的断言有3个核心问题,导致校验完全不生效:
- 属性名拼写错误:写的是
previousnums、nextsnums,实际schema中定义的属性为单数形式previousnum、nextsnum,多了后缀s导致根本选不到目标属性 - 节点路径错误:
previousnum、nextsnum是kPartsList的子元素(castOnPartSeg、joinPart、splitPart等各类零件节点)的属性,不是kPartsList节点自身的属性,原路径拿不到任何属性值 - 校验逻辑错误:原逻辑只判断
kPartsList下是否存在partNumber属性,完全没有做引用值和实际partNumber值的比对;且kpRefsList是空格分割的整数列表类型,原写法没有拆分列表值做逐一枚举校验
修正后的断言代码
直接把kPartsPiececomplexType下原来的两行assert替换为以下内容即可:
<!-- 校验所有previousnum引用值都在当前kPartsList的partNumber集合中存在 --> <xs:assert test="every $ref in kPartsList/*/@previousnum/data() satisfies $ref = kPartsList/*/@partNumber"/> <!-- 校验所有nextsnum引用值都在当前kPartsList的partNumber集合中存在 --> <xs:assert test="every $ref in kPartsList/*/@nextsnum/data() satisfies $ref = kPartsList/*/@partNumber"/>
逻辑说明
kPartsList/*/@previousnum:选中当前kPartsPiece下kPartsList所有直接子零件节点的previousnum属性,XPath会自动把列表类型的属性值拆分为单个整数的序列,不需要手动处理空格分割data():提取属性的原子值,避免节点类型不匹配导致的等值判断失效every ... satisfies:遍历序列里的每一个引用值,只要有一个值不在kPartsList所有子节点的partNumber集合中,断言就会返回false,触发校验失败
验证结果
你提供的XML示例可以正常通过该校验;如果故意把任意引用值改成不存在的partNumber(比如将某节点的nextsnum="1"改为nextsnum="999"),校验会直接报错,完全符合预期规则。另外你之前写的kPartsList下partNumber唯一的unique约束是有效的,等值匹配不会出现重复值导致的歧义。
内容的提问来源于stack exchange,提问作者piscvau
相关产品推荐
相关产品推荐

