如何在XML/XSD中基于属性名实现元素类型校验
校验失败的核心原因
你的条件类型分配写法有3个明显问题,导致规则无法生效:
xs:alternative是 XSD 1.1 版本专属特性,如果你使用的校验器仅支持XSD 1.0(比如多数编程语言内置的旧版XML校验组件),会直接忽略该规则,必须先切换到支持XSD 1.1的校验引擎(如Saxon、Apache Xerces 2.11及以上版本)。- 你直接引用内置
float、string类型作为匹配后的类型不符合你的XML结构:你的param元素除了文本内容,还携带name、type、libelle三个自定义属性,内置简单类型不支持绑定属性,必须自定义扩展自对应简单类型、包含属性声明的复杂类型。 - 匹配条件拼写错误:你XSD中写的匹配规则是
@name='Unité',但示例XML里第二个param的name属性值是Unit,规则永远无法命中。
修正后可正常运行的XSD代码
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"> <!-- name=Cste时的param类型:内容为浮点型,携带三个必填属性 --> <xs:complexType name="paramCsteType"> <xs:simpleContent> <xs:extension base="xs:float"> <xs:attribute name="name" type="xs:string" use="required" fixed="Cste"/> <xs:attribute name="type" type="xs:string" use="required"/> <xs:attribute name="libelle" type="xs:string" use="required"/> </xs:extension> </xs:simpleContent> </xs:complexType> <!-- name=Unit时的param类型:内容为字符串型,携带三个必填属性 --> <xs:complexType name="paramUnitType"> <xs:simpleContent> <xs:extension base="xs:string"> <xs:attribute name="name" type="xs:string" use="required" fixed="Unit"/> <xs:attribute name="type" type="xs:string" use="required"/> <xs:attribute name="libelle" type="xs:string" use="required"/> </xs:extension> </xs:simpleContent> </xs:complexType> <xs:element name="PARAMS"> <xs:complexType> <xs:sequence> <xs:element name="param" maxOccurs="unbounded" minOccurs="0"> <xs:alternative test="@name='Cste'" type="paramCsteType"/> <xs:alternative test="@name='Unit'" type="paramUnitType"/> <!-- 无test属性的兜底规则,匹配不到上述条件时触发,避免非法值漏校验 --> <xs:alternative> <xs:complexType> <xs:simpleContent> <xs:restriction base="xs:string"> <xs:pattern value=".*invalid param name.*"/> </xs:restriction> </xs:simpleContent> </xs:complexType> </xs:alternative> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>
补充说明
后续如果需要新增其他name值对应的内容校验规则,只需要先定义对应内容类型、包含对应属性声明的复杂类型,再在param元素下新增一条对应test条件的xs:alternative规则即可。
内容的提问来源于stack exchange,提问作者Mouaffak Djemali
相关产品推荐
相关产品推荐

