XSD复杂元素验证:能否验证特定格式的prod属性值?
用XSD验证这种格式的可行性
当然可以用XSD来验证这种格式!不过得看你用的是XSD 1.0还是1.1,两者的能力差异不小,我给你拆解说明:
如果你能使用XSD 1.1(推荐)
XSD 1.1支持断言(assertions)和字符串拆分功能,完美匹配你的需求——既能验证prod属性的产品:param1值:param2值格式,又能单独检查每个部分是否属于对应的参数列表。
具体实现步骤:
- 先为产品、param1、param2分别定义枚举类型,把允许的值都列进去:
<xs:simpleType name="ProductType"> <xs:restriction base="xs:string"> <xs:enumeration value="product1"/> <xs:enumeration value="product2"/> <!-- 按需添加更多产品 --> </xs:restriction> </xs:simpleType> <xs:simpleType name="Param1Type"> <xs:restriction base="xs:string"> <xs:enumeration value="val1a"/> <xs:enumeration value="val1b"/> <!-- 按需添加更多param1值 --> </xs:restriction> </xs:simpleType> <xs:simpleType name="Param2Type"> <xs:restriction base="xs:string"> <xs:enumeration value="val2a"/> <xs:enumeration value="val2b"/> <!-- 按需添加更多param2值 --> </xs:restriction> </xs:simpleType>
- 定义
entry元素时,用断言来验证prod属性:
<xs:element name="entry"> <xs:complexType> <xs:attribute name="prod" type="xs:string" use="required"/> <!-- 确保属性值恰好被冒号拆分成3部分 --> <xs:assert test="count(tokenize(@prod, ':')) = 3"/> <!-- 分别验证每一部分是否匹配对应的枚举类型 --> <xs:assert test="tokenize(@prod, ':')[1] castable as ProductType"/> <xs:assert test="tokenize(@prod, ':')[2] castable as Param1Type"/> <xs:assert test="tokenize(@prod, ':')[3] castable as Param2Type"/> </xs:complexType> </xs:element>
这样一来,任何不符合格式或者某部分不在允许列表里的prod值都会被XSD验证器拦截。
如果你只能用XSD 1.0
XSD 1.0不支持断言和动态字符串拆分,所以只能做妥协:
- 方案1:枚举所有可能的组合
把product:param1:param2的所有合法组合都列成枚举值,比如:
<xs:simpleType name="ValidProdCombination"> <xs:restriction base="xs:string"> <xs:enumeration value="product1:val1a:val2a"/> <xs:enumeration value="product1:val1a:val2b"/> <xs:enumeration value="product1:val1b:val2a"/> <xs:enumeration value="product2:val1a:val2a"/> <!-- 把所有合法组合都列出来 --> </xs:restriction> </xs:simpleType>
然后让entry的prod属性使用这个类型。但如果产品或参数值很多,这个方法会非常繁琐,维护成本很高。
- 方案2:仅验证格式
用正则表达式约束prod的格式,但不检查具体值是否在列表里:
<xs:simpleType name="ProdFormatType"> <xs:restriction base="xs:string"> <xs:pattern value="product[1-9][0-9]*:val1[a-z]:val2[a-z]"/> </xs:restriction> </xs:simpleType>
这种方式只能保证格式正确,但无法确保某个值(比如val1c)不在你的参数列表里。
总结
如果能升级到XSD 1.1,那肯定是最优解,既灵活又能精准验证每个部分;如果只能用XSD 1.0,就得根据你的参数数量和维护成本来选择合适的妥协方案。
内容的提问来源于stack exchange,提问作者Antek
相关产品推荐
相关产品推荐

