Как правильно использовать уникальные и ключевые ссылки в XML-схеме?

У меня есть эта XML-схема, но я не знаю, как ее заполнить, чтобы добиться того, что мне нужно. Я много искал в Интернете об использовании уникальных и ключевых ссылок, но все, что я могу найти, это основные примеры.

Это моя схема:

    <xs:element name="access" type="myaccess" />

    <xs:complexType name="myaccess">
        <xs:sequence>
            <xs:element name="user" type="myuser" minOccurs="0" maxOccurs="unbounded">
                <xs:unique name="u_idunique">
                    <xs:selector xpath="user" />
                    <xs:field xpath="@id" />
                </xs:unique>
            </xs:element>
            <xs:element name="authorization" type="myauthorization" minOccurs="0" maxOccurs="unbounded">

            <!-- HERE I WANT A KEYREF TO id attribute of user element -->
            <!-- HERE I WANT A KEYREF TO id attribute of building element OR door element -->

            </xs:element>
            <xs:element name="building" type="mybuilding" minOccurs="0" maxOccurs="unbounded" >
                <!-- I DON'T KNOW HOW TO SPECIFY THAT id of building, id of door and id of gate are in the same scope -->
                <xs:unique name="b_idunique">
                    <xs:selector xpath="building" />
                    <xs:field xpath="@id" />
                </xs:unique>
            </xs:element>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="myuser">
        <xs:attribute name="id" type="my_id" use="required" />
        <xs:attribute name="name" type="xs:string" use="required" />
        <xs:attribute name="phone" type="my_string_numeric" use="required" />
    </xs:complexType>

    <xs:complexType name="mybuilding">
        <xs:sequence>
            <xs:element name="door" type="mydoor" minOccurs="0" maxOccurs="unbounded">
                <!-- I DON'T KNOW HOW TO SPECIFY THAT id of building, id of door and id of gate are in the same scope -->
                <xs:unique name="d_idunique">
                    <xs:selector xpath="door" />
                    <xs:field xpath="@id" />
                </xs:unique>
            </xs:element>
        </xs:sequence>
        <xs:attribute name="id" type="my_id" use="required" />
        <xs:attribute name="name" type="xs:string" use="required" />
        <xs:attribute name="country" type="xs:string" use="required" />
    </xs:complexType>

    <xs:complexType name="mydoor">
        <xs:sequence>
            <xs:element name="gate" type="mygate" maxOccurs="unbounded">
                <!-- I DON'T KNOW HOW TO SPECIFY THAT id of building, id of door and id of gate are in the same scope -->
                <xs:unique name="g_idunique">
                    <xs:selector xpath="gate" />
                    <xs:field xpath="@id" />
                </xs:unique>
            </xs:element>
        </xs:sequence>
        <xs:attribute name="id" type="my_id" use="required" />
        <xs:attribute name="address" type="xs:string" use="required" />
        <xs:attribute name="status" type="mystatus" default="DISABLED" />
    </xs:complexType>

    <xs:complexType name="mygate">
        <xs:attribute name="id" type="my_id" use="required" />
        <xs:attribute name="type" type="mytype" use="required" />
        <xs:attribute name="status" type="mystatus" default="DISABLED" />
    </xs:complexType>

    <xs:complexType name="myauthorization">
        <xs:sequence>
            <xs:element name="validityperiod" type="myvalidityperiod" />
        </xs:sequence>
        <xs:attribute name="idu" type="my_id" use="required" />
        <xs:attribute name="idao" type="my_id" use="required" />
    </xs:complexType>

    <!-- OMITTED USELESS PART OF THE SCHEMA -->

</xs:schema>

У меня две проблемы:

  • Я не знаю, как указать, что поле идентификатора здания, поле идентификатора двери и поле идентификатора ворот находятся в одной области, и я не могу иметь 2 равных идентификатора (два здания не могут иметь одинаковый идентификатор , но также дверь и здание не могут иметь один и тот же идентификатор)
  • I don't know how to use correctly the keyref element.
    1. I'd like that idu filed of authorization element is an id that is present in one of the user elements (see [*] below).
    2. Я хотел бы, чтобы поле элемента авторизации idao было идентификатором, который присутствует в одном из элементов здания ИЛИ в одном из элементов двери.

[*] Я пытался написать это, но это не работает:

<xs:keyref name="useridkeyref" refer="u_idunique">
    <xs:selector xpath="authorization" />   
    <xs:field xpath="@idu" />
</xs:keyref>

Я знаю, что это не короткий вопрос, и я заранее благодарю всех за то, что прочитали его. Я надеюсь, что смогу получить некоторую помощь. Благодарю вас!


person Manuel Durando    schedule 18.12.2013    source источник


Ответы (2)


Уникальные ограничения и ключи имеют область видимости на уровне element — вам нужно поместить ограничение не внутри каждого отдельного элемента, а внутри элемента access, который является их общим предком.

<xs:element name="access" type="myaccess">
  <xs:key name="user_id">
    <xs:selector xpath="user" />
    <xs:field xpath="@id" />
  </xs:key>
  <xs:key name="access_id">
    <xs:selector xpath="building | building/door | building/door/gate" />
    <xs:field xpath="@id" />
  </xs:key>
  <xs:keyref name="user_ref" refer="user_id">
    <xs:selector xpath="authorization" />
    <xs:field xpath="@idu" />
  </xs:keyref>
  <xs:keyref name="access_ref" refer="access_id">
    <xs:selector xpath="authorization" />
    <xs:field xpath="@idao" />
  </xs:keyref>
</xs:element>
person Ian Roberts    schedule 18.12.2013
comment
Спасибо за ответ! Мне действительно очень помогло! Но все еще есть проблема: когда я проверяю XML по схеме, я получаю эту ошибку: ключ «access_ref» со значением «B4D1» не найден для ограничения идентичности элемента «доступ». Все авторизации, относящиеся к зданию, в порядке, но те, которые относятся к двери, не работают, и я не могу понять, почему. - person Manuel Durando; 18.12.2013
comment
Это фрагмент XML, который выдает мне ошибку: ‹авторизация idu=U6 idao=B4D1› ‹период действия с=2014-03-31T01:49:45.000+02:00 до=2014-04-07T17:01:48.000 +02:00/› ‹/авторизация› - person Manuel Durando; 18.12.2013
comment
Хорошо, я думаю, что решил сам: важен порядок путей в селекторе xpath для access_id, я исправил его на ‹xs:selector xpath=building/door/gate | здание/дверь | здание /› Спасибо за полезный ответ! - person Manuel Durando; 20.12.2013
comment
@ManuelDurando Я не вижу в спецификации ничего, что требовало бы этого - порядок альтернатив не должен иметь значения в выражении xpath, поэтому вы можете отправить отчет об ошибке для любого используемого вами валидатора схемы. - person Ian Roberts; 20.12.2013

В моем случае мне также пришлось объявить и использовать явное пространство имен для селекторов. Используйте решение из Ian Roberts и адаптируйте эти атрибуты:

<xs:schema ...
        xmlns:mc="http://mycompany.com"
...
>
...    
    <xs:selector xpath="mc:user" />      
  ...      
    <xs:selector xpath="mc:authorization" />
  ...
 </xs:element>

См. также здесь https://stackoverflow.com/a/22353694/1909531

person Matthias M    schedule 04.06.2018