Ключ XML Schema / keyref - как их использовать? - PullRequest
25 голосов
/ 20 декабря 2010

Короче говоря: я хотел бы знать, как использовать ключ / keyref из XSD, чтобы элементы имели ссылки друг на друга.он должен иметь форму примера с использованием простого xsd и XML.

Длинная история: я знаком с использованием ID / IDREF.Я использую их для подключения элементов для JAXB.Мне неоднократно говорили, что конструкция key / keyref в XSD предлагает повышенную гибкость для межэлементных ссылок.Я ознакомился с книгой OReilly XML Schema , которая, кажется, учит всему правильному определению key / keyref и тому, как он похож на ID / IDREF (но лучше), и не дает простого примераего использование.Похоже, что это не похоже, потому что вы определяете ID как атрибут в одном элементе и IDREF в другом элементе и вуаля.Но ключ / keyref должны быть определены в общем предке ссылки и ссылочного элемента (AFAIK) ...

Я использую файлы XSD для генерации связанных с JAXB Java-классов с XJC

Я искал инструкции, учебники и примеры, но Google дает мне записки.То же самое для поисков на SO (также с Google и включенным поиском с '+').

Чтобы облегчить жизнь всем, я подготовил XSD с уже определенной парой ключ / ключ, как я ее понял.

<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="root">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="referenced">
                <xs:complexType>
                    <xs:attribute name="id" type="xs:string" />
                </xs:complexType>
            </xs:element>
            <xs:element name="owner">
                <xs:complexType>
                    <xs:attribute name="id" type="xs:string" />
                </xs:complexType>
            </xs:element>
        </xs:sequence>
    </xs:complexType>
    <xs:key name="aKey">
        <xs:selector xpath="owner" />
        <xs:field xpath="@id" />
    </xs:key>
    <xs:keyref name="aKeyRef" refer="aKey">
        <xs:selector xpath="referenced" />
        <xs:field xpath="@id" />
    </xs:keyref>
</xs:element>

Как будет выглядеть фрагмент XML с элементом-владельцем, ссылающимся на элемент-ссылка?

РЕДАКТИРОВАТЬ: применил изменение, предложенное Томом В., изменив атрибут xpath ключевого элемента на «владелец».JAXB (XJC) по-прежнему все равно.

Спасибо

Ответы [ 5 ]

6 голосов
/ 20 декабря 2010

В экземпляре документа нет специального синтаксиса. Просто требуется, чтобы узел keyref соответствовал существующему узлу ключа. Валидация покажет вам, удовлетворено ли ключевое ограничение.

RE ваш код:

Я только что сам начал баловаться с ключами, но я думаю, что заметил вашу ошибку - aKey должно выглядеть так:

<xs:key name="aKey">
    <xs:selector xpath="owner" />
    <xs:field xpath="@id" />
</xs:key>

Более того - это надо понимать - ограничения ключа не распознают пространство имен по умолчанию. Вы всегда должны ставить перед каждой частью selector xpath префикс пространства имен для искомого элемента. Если у вас нет префикса пространства имен - жесткий, вам нужно добавить его. Это ограничение стандарта.

5 голосов
/ 21 декабря 2010

Спецификация JAXB явно не охватывает key / keyref. Однако реализации JAXB, такие как EclipseLink MOXy (я технический руководитель), имеют расширения для этого. В нашем следующем выпуске 2.2 предусмотрены средства для определения такого рода отношений с помощью аннотаций (я приведу пример). Ниже приведена ссылка на то, как это можно сделать с помощью текущей версии.

Для получения дополнительной информации см .:

UPDATE

Я надеялся получить пример, включенный в ответ, но у меня заканчивается время, прежде чем я уезжаю в отпуск. Ниже приведен пример из нашей проектной документации, которая демонстрирует концепцию:

4 голосов
/ 09 декабря 2015

Я обнаружил, что этот поток ищет то же самое, что искал OP - простой пример использования элемента <xs:key>. Все вещи JAXB были греческими для меня и отвлекающими. Для других, кто найдет эту ветку позже, вот простой пример, опубликованный на MSDN через пару лет после того, как OP задал вопрос здесь на SO:

https://msdn.microsoft.com/en-us/library/ms256101%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396

В случае изменения ссылки MSDN путь крошки был:

https://msdn.microsoft.com/library, затем нажмите «Переключиться в представление оглавления библиотеки», и просверлите:

Библиотека MSDN> Разработка .NET> .NET Framework 4.6 и 4.5> Руководство по разработке> Данные и моделирование> Справочник по стандартам XML> Справочник по схемам XML (XSD)> Элементы схемы XML> Элемент

3 голосов
/ 23 октября 2016

Пожалуйста, попробуйте посмотреть этот учебник ключей / ключей .

Цветной текст очень полезен.

3 голосов
/ 20 декабря 2010

JAXB не поддерживает ссылки с помощью xs:key или xs:keyref. В спецификации говорится, что эти ограничения могут быть проверены во время проверки, но они не влияют на данные.

Однако вы можете достичь этого (более или менее), используя xs:ID и xs:IDREF. Введение см. В главах 2.2.15. Обращение к другому элементу XML и 4.3. Сборка данных со ссылками (ID, IDREF) в руководстве по JX1011 * AXB by Вольфганг Лаун.

Для вашего образца XSD это означало бы изменение определения элемента на

<xs:element name="root">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="referenced">
                <xs:complexType>
                    <xs:attribute name="id" type="xs:ID" />
                </xs:complexType>
            </xs:element>
            <xs:element name="owner">
                <xs:complexType>
                    <xs:attribute name="id" type="xs:IDREF" />
                </xs:complexType>
            </xs:element>
        </xs:sequence>
    </xs:complexType>
</xs:element>

Обратите внимание, что идентификаторы с типом xs:ID должны быть глобально уникальными в документе XML. Другими словами, вы не можете иметь один и тот же идентификатор для двух разных элементов в одном и том же XML-файле, даже если элементы имеют разные типы.

По умолчанию элемент или атрибут типа xs:IDREF связывается с java.lang.Object. Если вы заранее знаете, каким будет тип ссылочного объекта, вы можете настроить отображение, добавив аннотации JAXB в схему или с помощью объявления внешней привязки (например, xjc -b bindings.xjb).

Пример использования аннотаций схемы JAXB (не тестировался):

<xs:element name="owner">
    <xs:complexType>
        <xs:attribute name="id" type="xs:IDREF">
            <xs:annotation>
                <xs:appinfo>
                    <jaxb:property>
                        <jaxb:baseType name=”SomeType”/>
                    </jaxb:property>
                </xs:appinfo>
            </xs:annotation>
        </xs:attribute>
    </xs:complexType>
</xs:element>

Пример использования объявления внешних привязок (не проверено):

<jaxb:bindings node="//xs:element[@name=’owner’]//xs:attribute[@name='id']”>
    <jaxb:property>
        <jaxb:basetype name="SomeType"/>
    </jaxb:property>
</jaxb:bindings>
...