2015-12-30 2 views
2

все! Это мой первый вопрос о stackoverflow, хотя я регулярно читаю сообщения на этом сайте.Уникальные элементы и атрибуты XSD

Чтобы добраться до точки, я пытаюсь определить XML-схему, которая выглядит следующим образом:

<xs:element name="keyConfiguration"> 
<xs:complexType> 
    <xs:sequence> 
    <xs:element name="move"> 
     <xs:complexType> 
     <xs:attribute name="N" type="keyCode"/> 
     <xs:attribute name="NE" type="keyCode"/> 
     <xs:attribute name="E" type="keyCode"/> 
     <xs:attribute name="SE" type="keyCode"/> 
     <xs:attribute name="S" type="keyCode"/> 
     <xs:attribute name="SW" type="keyCode"/> 
     <xs:attribute name="W" type="keyCode"/> 
     <xs:attribute name="NW" type="keyCode"/> 
     </xs:complexType> 
    </xs:element> 
    <xs:element name="wait" type="keyCode"/> 
    <xs:element name="select" type="keyCode"/> 
    </xs:sequence> 
</xs:complexType> 
<xs:unique name="uniqueKeyCode"> 
    <xs:selector xpath="."/> 
    <xs:field xpath="move/@*"/> 
    <xs:field xpath="wait"/> 
    <xs:field xpath="select"/> 
</xs:unique> 

keyCode является типом перечисления, используемый для идентификации нажатий клавиатуры и принимает подмножество xs:int.

Идея заключается в том, что я не хочу, чтобы проверить XML-файлы, которые отображают множество возможных действий в том же ключе, так что следующий XML должен быть недействительны:

<keyConfiguration> 
    <move N="101" NE="101" E="102" SE="99" S="98" SW="97" W="100" NW="103"/> 
    <wait>101</wait> 
    <select>101</select> 
</keyConfiguration> 

Оба атрибута для перемещения на Север, Север -East и т. Д., А элементы для действий ожидания/выбора повторяются, и ни одно из них не должно происходить. Все атрибуты для направлений движения и всех элементов для других действий должны быть уникальными.

К сожалению, когда я пытаюсь проверить данный XML на XSD, он действителен! Я думаю, что XPath в уникальном теге сломаны, но я не знаю, как это исправить (я пробовал несколько вариантов, включая <xs:field xpath="*/move/@*"/> и <xs:field xpath="*/wait"/>, и он все еще не работал).

Заранее благодарен!

Edit: здесь полное определение схемы, если это помогает:

<?xml version="1.0" encoding="UTF-8"?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:simpleType name="keyCode"> 
    <xs:restriction base="xs:int"> 
     <xs:enumeration value="10"/> <!-- Enter --> 
     ... 
     <xs:enumeration value="96"/> <!-- NumPad-0 --> 
     <xs:enumeration value="97"/> <!-- NumPad-1 --> 
     <xs:enumeration value="98"/> <!-- NumPad-2 --> 
     <xs:enumeration value="99"/> <!-- NumPad-3 --> 
     <xs:enumeration value="100"/> <!-- NumPad-4 --> 
     <xs:enumeration value="101"/> <!-- NumPad-5 --> 
     <xs:enumeration value="102"/> <!-- NumPad-6 --> 
     <xs:enumeration value="103"/> <!-- NumPad-7 --> 
     <xs:enumeration value="104"/> <!-- NumPad-8 --> 
     <xs:enumeration value="105"/> <!-- NumPad-9 --> 
     ... 
     </xs:restriction> 
    </xs:simpleType> 

    <xs:element name="keyConfiguration"> 
    <xs:complexType> 
     <xs:sequence> 
     <xs:element name="move"> 
      <xs:complexType> 
      <xs:attribute name="N" type="keyCode"/> 
      <xs:attribute name="NE" type="keyCode"/> 
      <xs:attribute name="E" type="keyCode"/> 
      <xs:attribute name="SE" type="keyCode"/> 
      <xs:attribute name="S" type="keyCode"/> 
      <xs:attribute name="SW" type="keyCode"/> 
      <xs:attribute name="W" type="keyCode"/> 
      <xs:attribute name="NW" type="keyCode"/> 
      </xs:complexType> 
     </xs:element> 
     <xs:element name="wait" type="keyCode"/> 
     <xs:element name="select" type="keyCode"/> 
     </xs:sequence> 
    </xs:complexType> 
    <xs:unique name="uniqueKeyCode"> 
    <xs:selector xpath="."/> 
     <xs:field xpath="*/move/@*"/> 
     <xs:field xpath="*/wait"/> 
     <xs:field xpath="*/select"/> 
    </xs:unique> 
    </xs:element> 
</xs:schema> 

Может быть, это что-то делать с пространством имен? Я пробовал смотреть в Интернете с примерами xpath, но я не мог найти ничего, что помогло бы мне идентифицировать проблему. Благодаря!

ответ

3

Не думаю, что это можно сделать с помощью XSD 1.0. Уникальный работает таким образом: xs: selector выбирает набор элементов, в которых поля значение должно быть уникальным.

Так, в селекторе вы должны выбрать каждый атрибут, значение и значение , а в поле Значение этих узлов (символ точки «»). Имейте в виду, что в XPath оператор | дает соединение между наборами узлов. В идеале вы могли бы использовать это, чтобы решить вашу проблему:

<xs:unique name="uniqueKeyCode"> 
    <xs:selector xpath="move/@* | wait | select"/> 
    <xs:field xpath="."/> 
</xs:unique> 

Однако XSD не позволяет выбрать атрибуты хз: селекторные. Но я надеюсь, вы понимаете, что если N, NE, W и т.д. были elemnts вместо атрибутов вам разрешено использовать что-то вроде следующего, и он будет работать:

<xs:unique name="uniqueKeyCode"> 
    <xs:selector xpath="move/* | wait | select"/> 
    <xs:field xpath="."/> 
</xs:unique> 

И это будет работать потому что вы выбираете только элементы в xs: selector.

Использование XSD 1.1 это можно сделать с помощью xs: assert, который позволяет использовать xpath (селектор, поле, уникальный и т. Д., Только позволяет использовать ограниченное подмножество XPath).Пример утверждение, что позволит решить эту проблему:

<xs:assert test="count(distinct-values(move/@* | wait | select)) = count(move/@* | wait | select)"/> 

В дополнение иметь в виду, что легче определить тип KeyCode используя диапазоны (от 10 до 105), а также с помощью объединения (от 10 до 50 + от 60 до 105) вместо использования xs: перечисление.

Пример Удерживание значения:

<xs:simpleType name="keyCode"> 
    <xs:restriction base="xs:int"> 
     <xs:minInclusive value="10"/> 
     <xs:maxInclusive value="105"/> 
    </xs:restriction> 
</xs:simpleType> 

Пример для не непрерывных значений:

<xs:simpleType name="keyCode"> 
    <xs:union> 
     <xs:simpleType> 
      <xs:restriction base="xs:int"> 
       <xs:minInclusive value="10"/> 
       <xs:maxInclusive value="50"/> 
      </xs:restriction> 
     </xs:simpleType> 

     <xs:simpleType> 
      <xs:restriction base="xs:int"> 
       <xs:minInclusive value="60"/> 
       <xs:maxInclusive value="105"/> 
      </xs:restriction> 
     </xs:simpleType> 
    </xs:union> 
</xs:simpleType> 
+0

Большое спасибо, это именно то, что мне нужно! Я очень ценю, что вы нашли время, чтобы написать ответ! –

+0

Добро пожаловать. Рад, что смог помочь :) – sergioFC

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