2010-12-20 2 views
24

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

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

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

Я искал для справки, учебники и примеры, но google дает мне обрывки. то же самое для поисков на SO (также с поиском google и inclusive с «+»).

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

<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'-элемент?

EDIT: применил изменение, предложенное Tom W, изменив атрибут xpath ключевого элемента на «owner». Однако JAXB (XJC) все равно не заботится.

Спасибо

ответ

6

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

RE код:

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

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

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

+0

aah, вот почему нет атрибута. Я применил указанное вами изменение, но JAXB ничего не генерирует, чтобы иметь доступ к ссылочному элементу от владельца - вся часть key/keyref, похоже, не влияет на отображение. Есть ли еще что-то, что мне не хватает? – kostja

+0

Я хотел сказать, что XJC не генерирует ... – kostja

+0

Возможно, я должен уточнить, что я говорю в вышеупомянутом сообщении. Я не знаю, что такое JAXB, но это не имеет никакого значения. Я пытаюсь сказать, что говоря <владелец OtherItemID = "1" /> ... . . все, что вам нужно, чтобы выразить ключевое отношение, нет синтаксиса xml, чтобы специально объявить ключевое отношение в экземпляре. Я предполагаю, что вы имеете в виду, что вы используете фреймворк, который должен функционировать как ORM для xml-файлов, и в этом случае вы можете ожидать какой-то значимый вывод, и в этом случае попробуйте сыграть с объемом ключа и keyref на перемещая их. –

2

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

Однако вы можете достичь этого (более или менее), используя вместо этого xs:ID и xs:IDREF. Для ознакомления см. Главы 2.2.15 Referring to Another XML Element и 4.3 Assembling Data with Links (ID, IDREF) в J AXB Tutorial от Вольфганга Лауна.

Для вашего образца 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> 
+0

** markusk ** ответил, что я явно не знал, но догадался, в чем дело. Если вы можете положиться на проверку, чтобы обеспечить соблюдение этих ограничений в ваших бизнес-данных, я не думаю, что использование ключей должно быть проблемой, но из этого я думаю, что JAXB вам не поможет. Удачи! –

+0

спасибо. это выглядит так же, как материал, который я делаю сейчас :) Это работает нормально, но для того, чтобы иметь иллюзию безопасности типов, вы должны вручную изменить ссылки в сгенерированных классах владельца из Object в настоящий ссылочный класс. И theres никакая дорога иметь реальную безопасность типа. Это своего рода отстой, я действительно хотел бы обеспечить его соблюдение и думал, что это возможно с помощью key/keyref. – kostja

+0

@kostja: вы можете настроить сопоставление JAXB, чтобы указать ссылочный класс. Я обновил свой ответ с помощью (непроверенных) образцов того, как это сделать. – markusk

5

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

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

UPDATE

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

+0

спасибо, это выглядит многообещающим. я действительно с нетерпением жду вашего примера – kostja

4

Я нашел эту тему на поиске того же ОП искали - простой пример использования этого <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 Library> разработки .NET> .NET Framework 4.6 и 4.5> Руководство по разработке> данных и моделирование> XML Standards Reference> XML-схем (XSD) Ссылка> XML-схема Элементы> < xsd: key> Элемент

Смежные вопросы