XSD: проверка ключей и ключей - PullRequest
1 голос
/ 25 ноября 2011

У меня проблемы с проверкой схемы, это мой xml

<?xml version="1.0" encoding="utf-8" ?>
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:noNamespaceSchemaLocation='favorites.xsd'>
    <Favorites>
        <Folder>
            <Name>Entertainment</Name>
            <Bookmarks>
                <Bookmark ID="1"/>
                <Bookmark ID="200"/> <!-- This should fail validation -->
            </Bookmarks>
        </Folder>
    </Favorites>
    <Bookmarks>
        <Bookmark>
            <ID>1</ID>
            <URL>www.website1.com</URL>
        </Bookmark>
        <Bookmark>
            <ID>2</ID>
            <URL>www.website2.com</URL>
        </Bookmark>
        <Bookmark>
            <ID>3</ID>
            <URL>www.website3.com</URL>
        </Bookmark>
    </Bookmarks>
</root>

Элемент идентификатора в Закладке должен быть ключевым, а атрибут «Избранное» / «Папка / Закладки / Идентификатор закладки» всегда должен ссылаться на идентификатор закладки.

Вот мой xsd:

<?xml version="1.0"?>
<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'>
    <xs:element name="root">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="Favorites" type="Favorites"/>
                <xs:element name="Bookmarks" type="Bookmarks"/>
            </xs:sequence>
        </xs:complexType>
        <xs:keyref name="bookmarkIDKeyRef" refer="bookmarkIDKey">
            <xs:selector xpath="root/Favorites/Folder/Bookmarks/*"/>
            <xs:field xpath="@ID"/>
        </xs:keyref>
        <xs:key name="bookmarkIDKey">
            <xs:selector xpath="root/Bookmarks/Bookmark/ID"/>
            <xs:field xpath="ID"/>
        </xs:key>
    </xs:element>

    <xs:complexType name="Favorites">
        <xs:sequence maxOccurs="unbounded">
            <xs:element name="Folder" type="Folder"/>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="Folder">
        <xs:sequence>
            <xs:element name="Name" type="xs:string"/>
            <xs:element name="Bookmarks">
                <xs:complexType>
                    <xs:sequence maxOccurs="unbounded">
                        <xs:element name="Bookmark">
                            <xs:complexType>
                                <xs:attribute name="ID" type="xs:string"/>
                            </xs:complexType>
                        </xs:element>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="Bookmarks">
        <xs:sequence maxOccurs ="unbounded">
            <xs:element name="Bookmark" type="Bookmark"/>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="Bookmark">
        <xs:sequence>
            <xs:element name="ID" type="xs:string"/>
            <xs:element name="URL" type ="xs:string"/>
        </xs:sequence>
    </xs:complexType>

</xs:schema>

xml правильно сформирован, но проверка атрибута ID не работает.

1 Ответ

1 голос
/ 26 ноября 2011

Контекст ваших ключей - это элемент <root>, потому что в схеме они являются дочерними элементами элемента <xs:element name="root">. Поэтому ваши <xs:selector> XPath не работают, потому что они начинаются с root/..., который не является потомком элемента <root>. Бросьте его для key и keyref. Также ключ <xs:field> не работает из-за аналогичной проблемы. Вы уже выбираете элемент <ID> в качестве контекста, а затем пытаетесь найти дочерний элемент <ID> для этого элемента. Переключите XPath <xs:field> на . (точка) или сбросьте конечный /ID с селектора.

Вот пример рабочего кода.

<xs:element name="root">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="Favorites" type="Favorites"/>
            <xs:element name="Bookmarks" type="Bookmarks"/>
        </xs:sequence>
    </xs:complexType>
    <xs:keyref name="bookmarkIDKeyRef" refer="bookmarkIDKey">
        <xs:selector xpath="Favorites/Folder/Bookmarks/*"/>
        <xs:field xpath="@ID"/>
    </xs:keyref>
    <xs:key name="bookmarkIDKey">
        <xs:selector xpath="Bookmarks/Bookmark"/>
        <xs:field xpath="ID"/>
    </xs:key>
</xs:element>
...