XSD unique约束selector指定plc未触发校验问题排查
问题根源
你的配置错误核心是 selector的XPath表达式未适配带命名空间的元素匹配规则。
原因解释
- 你的XSD声明了
targetNamespace="foobar",且开启了elementFormDefault="qualified",这意味着XML中所有定义的元素(包括piconfig和它的子元素plc)都属于foobar命名空间。 - XSD中
selector的XPath表达式默认是匹配无命名空间的元素,你写的xpath="plc"只能命中不属于任何命名空间的plc元素,自然匹配不到你带foobar命名空间的目标元素,所以唯一性约束不触发。 - 换成
*后生效是因为通配符*会忽略命名空间匹配所有子元素,刚好命中了plc元素,所以约束正常工作。
正确修改方案
首先给XSD的目标命名空间绑定自定义前缀,再修改selector的XPath为带前缀的路径即可:
<?xml version="1.1" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:my="foobar" targetNamespace="foobar" elementFormDefault="qualified"> <xs:element name="piconfig"> <xs:complexType> <xs:sequence maxOccurs="unbounded"> <xs:element name="plc"> <xs:complexType> <xs:attribute name="name" type="xs:string" use="required"/> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> <xs:unique name="UniquePlcName"> <!-- 带命名空间前缀匹配plc元素 --> <xs:selector xpath="my:plc"/> <xs:field xpath="@name"/> </xs:unique> </xs:element> </xs:schema>
另外注意你的测试XML中命名空间声明有误,要和XSD的targetNamespace保持一致:
<?xml version="1.1" encoding="UTF-8"?> <piconfig xmlns="foobar"> <plc name="foobar"/> <plc name="foobar"/> </piconfig>
修改后重复name的XML就会正常触发唯一性校验失败。
内容的提问来源于stack exchange,提问作者Stefan May
相关产品推荐
相关产品推荐

