Tengo un archivo 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>

Y una instancia 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>

Utilizo este validador para probar mis documentos.

Lo que supongo es que la instancia XML no debería ser válida ya que ambos nombres de libros en una biblioteca son Hihi, lo que significa que cada nombre de libro no es único en absoluto.

Intenté agregar un prefijo de espacio de nombres a todo, moviendo los elementos xs:unique al elemento book, pero todo eso no funciona y los validadores XML dicen que el documento es válido.

¿Qué he hecho mal? Cualquier ayuda será muy apreciada.

1
Chung Lun Yuen 13 dic. 2016 a las 17:48

2 respuestas

La mejor respuesta

Dices "He intentado agregar un prefijo de espacio de nombres a todo", pero aparentemente cometiste un error allí, porque ese es el problema de tu esquema.

Las declaraciones de espacio de nombres normales no se aplican a las expresiones XPath.

En XML Schema 1.1, simplemente puede agregar xpathDefaultNamespace="##defaultNamespace" al elemento xs:schema.

En XML Schema 1.0, es necesario agregar un prefijo explícito para el espacio de nombres predeterminado y usar ese prefijo en las restricciones:

<?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>

Tenga en cuenta que library no es un buen nombre de espacio de nombres. Debe ser un URI adecuado, por ejemplo, http://example.com/library, pero por supuesto para su propio dominio. No es necesario que el URI sea desreferenciable, pero debe ser único para evitar conflictos de nombres.

1
Meyer 13 dic. 2016 a las 15:39

Como la respuesta anterior era correcta, también puede modificar su xsd a:

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

Y en tu XML:

 <library xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
0
Dominique Duvar 13 dic. 2016 a las 15:34