使用Xerces验证XSD 1.1时遇xs:assert元素错误及规则实现问题
解决XSD 1.1断言错误与业务规则实现问题
一、修复s4s-elt-invalid-content.1错误
这个错误的核心原因是<xs:assert>元素放置位置不符合XSD 1.1规范:
<xs:assert>必须作为<xs:complexType>的直接子元素,且要放在内容模型定义(如<xs:sequence>、<xs:all>)之后,不能嵌套在内容模型内部,也不能放在错误的层级节点下。
示例正确结构:
<xs:complexType name="ModeloType"> <xs:sequence> <xs:element name="disponible" type="StatusType" nillable="true"/> <xs:element name="bloqueado" type="StatusType" nillable="true"/> <xs:element name="cancelado" type="StatusType" nillable="true"/> <!-- 其他元素 --> </xs:sequence> <!-- 断言必须放在内容模型之后 --> <xs:assert test="..."/> <xs:assert test="..."/> </xs:complexType>
二、实现业务规则的完整XSD定义
1. 定义元素取值类型
先创建一个联合类型,支持0、正整数、空值或definitivo:
<xs:simpleType name="StatusType"> <xs:union memberTypes="xs:nonNegativeInteger"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:enumeration value="definitivo"/> <xs:enumeration value=""/> <!-- 允许空字符串 --> </xs:restriction> </xs:simpleType> </xs:union> </xs:simpleType>
2. 添加断言实现业务规则
在ModeloType的complexType中添加三个断言,分别对应业务规则:
<xs:complexType name="ModeloType"> <xs:sequence> <xs:element name="disponible" type="StatusType"/> <xs:element name="bloqueado" type="StatusType"/> <xs:element name="cancelado" type="StatusType"/> </xs:sequence> <!-- 规则1:三个元素最多一个为'definitivo' --> <xs:assert test="count(disponible[.='definitivo']) + count(bloqueado[.='definitivo']) + count(cancelado[.='definitivo']) ≤ 1"/> <!-- 规则2:disponible为'definitivo'时,bloqueado与cancelado之和为0(空值视为0) --> <xs:assert test="not(disponible='definitivo') or (number(if(bloqueado='') then 0 else bloqueado) + number(if(cancelado='') then 0 else cancelado) = 0)"/> <!-- 规则3:bloqueado为'definitivo'时,cancelado为0或空 --> <xs:assert test="not(bloqueado='definitivo') or (cancelado='' or cancelado='0')"/> </xs:complexType>
三、解决断言评估失败问题
1. 确认Xerces启用XSD 1.1支持
Xerces 2.12.2默认未开启XSD 1.1验证,需在代码中手动设置:
SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/XML/XMLSchema/v1.1"); // 启用1.1特性 factory.setFeature("http://apache.org/xml/features/validation/schema/1.1", true); Schema schema = factory.newSchema(new File("your-schema.xsd")); Validator validator = schema.newValidator();
2. 检查XML实例是否符合规则
比如违反规则的XML实例:
<modelo> <disponible>definitivo</disponible> <bloqueado>5</bloqueado> <!-- 违反规则2 --> <cancelado>0</cancelado> </modelo>
这种情况会触发断言失败,需修正XML使其符合所有规则。
3. 验证XPath表达式正确性
确保断言中的XPath能正确定位元素,注意:
- 若元素是可选的,需补充
exists()判断 - 空值转换为0的逻辑要覆盖所有场景
内容的提问来源于stack exchange,提问作者Marco Osorio
相关产品推荐
相关产品推荐

