Ключ XML Schema /keyref - как их использовать?

Короче говоря: я хотел бы знать, как использовать ключ /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 с элементом "owner", ссылающимся на элемент "referenced"?

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

Спасибо

5 ответов

Я обнаружил, что этот поток ищет то же самое, что искал 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> Элемент

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

RE ваш код:

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

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

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

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

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

ОБНОВИТЬ

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

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

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

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

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

Для вашего образца 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>
Другие вопросы по тегам