xsd xs:unique无法检测到重复项

时间:2016-12-13 14:48:15

标签: xml xpath xsd unique xml-namespaces

我有一个XSD文件:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="library"
           xmlns="library"
           elementFormDefault="qualified">

    <xs:element name="library">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="book" minOccurs="1" maxOccurs="unbounded"/>
            </xs:sequence>
        </xs:complexType>

        <xs:unique name="book-name">
            <xs:selector xpath="book"/>
            <xs:field xpath="name"/>
        </xs:unique>
    </xs:element>

    <xs:element name="book">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="name" type="xs:string" minOccurs="1" maxOccurs="1"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

</xs:schema>

和xml-instance:

<library xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xsi:schemaLocation="library uniqueness.xsd"
         xmlns="library">
    <book>
        <name>Hihi</name>
    </book>
    <book>
        <name>Hihi</name>
    </book>
</library>

我使用this验证程序来测试我的文档。

我认为,XML实例应该无效,因为库中的两个书名都是Hihi,这意味着每个书名都不是唯一的。

我尝试将名称空间前缀添加到所有内容中,将xs:unique元素移动到元素book,但所有这些都不起作用,XML验证程序说该文档有效。

我做错了什么?任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:1)

你说“我尝试过为所有内容添加名称空间前缀”, 但似乎你在那里犯了一个错误,因为这是你的架构的问题。

常规名称空间声明不适用于XPath表达式。

在XML Schema 1.1中,您只需将xpathDefaultNamespace="##defaultNamespace"添加到xs:schema元素即可。

在XML Schema 1.0中,有必要为默认命名空间添加显式前缀,并在约束中使用该前缀:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="library"
           xmlns="library"
           xmlns:lib="library"
           elementFormDefault="qualified">

    <xs:element name="library">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="book" maxOccurs="unbounded"/>
            </xs:sequence>
        </xs:complexType>

        <xs:unique name="book-name">
            <xs:selector xpath="lib:book"/> <!-- Prefixed -->
            <xs:field xpath="lib:name"/>    <!-- Prefixed -->
        </xs:unique>
    </xs:element>

    <xs:element name="book">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="name" type="xs:string"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

</xs:schema>

请注意library不是一个好的命名空间名称。它应该是一个合适的URI,例如http://example.com/library,但当然对于您自己的域。 URI不需要是可解除引用的,但它应该是唯一的,以便避免名称冲突。

答案 1 :(得分:0)

作为前面的答案是正确的,您也可以将xsd修改为:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"  elementFormDefault="qualified">

并在您的XML中:

 <library xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">