xsd xs:unique 未能检测到重复项

xsd xs:unique failed to detect duplicates

我有一个 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-实例:

<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 验证器说文档有效。

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

你说"I have tried adding namespace prefix to everything", 但似乎你在那里犯了一个错误,因为那是你的架构问题。

常规命名空间声明不适用于 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 不需要是可取消引用的,但它应该是唯一的以避免名称冲突。

前面的回答是对的,你也可以修改你的xsd为:

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

在你的 XML 中:

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