Проверка XSD: N дочерних элементов с дополнительными различными ограничениями

У меня есть XML, который я хочу проверить с помощью XSD. На самом деле это простой сценарий, но я не мог найти правильный ответ. Это XML:

<data>
  <point>
    <x>count</x>
    <y>218</y>
  </point>
  <point>
    <x>maxtime</x>
    <y>1</y>
  </point>
  <point>
    <x>mintime</x>
    <y>0</y>
  </point>
  <point>
    <x>mean</x>
    <y>0.11</y>
  </point>
</data>

Я хочу убедиться, что элемент data содержит 4 элемента point и что есть только один с x element = count , только один с x = maxtime ...

Теперь у меня есть следующее:

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="data">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="point" type="ctPoint" minOccurs="1" maxOccurs="4" />
        </xs:sequence>
    </xs:complexType>
</xs:element>

<xs:complexType name="ctPoint">
    <xs:sequence minOccurs="1" maxOccurs="4">
        <xs:element name="x" minOccurs="1" maxOccurs="1">
            <xs:simpleType>
                <xs:restriction base="xs:string">
                    <xs:enumeration value="count" />
                    <xs:enumeration value="maxtime" />
                    <xs:enumeration value="mintime" />
                    <xs:enumeration value="mean" />
                </xs:restriction>
            </xs:simpleType>
        </xs:element>
        <xs:element name="y" type="xs:decimal" minOccurs="1" maxOccurs="1" />
    </xs:sequence>
</xs:complexType>

This validates correctly but it does not guarantee that there is only 1 count, only 1 maxtime,…


person Dennis De Reyer    schedule 03.12.2014    source источник
comment
Скорее всего, у вас не получится с XSD 1.0. Вы можете использовать XSD 1.1?   -  person lexicore    schedule 03.12.2014
comment
Я также могу использовать XSD 1.1, но как мне это там сделать?   -  person Dennis De Reyer    schedule 03.12.2014
comment
Если я правильно понимаю вашу проблему, это также возможно в XSD 1.0 с использованием xs: unique (см. Мой ответ).   -  person sergioFC    schedule 05.12.2014


Ответы (2)


I want to make sure that the data element contains 4 point elements

Это ограничение можно легко обойти с помощью minOccurs="4" и maxOccurs="4" XSD 1.0.

и что есть только один с x element = count, только один с x = maxtime ...

Это ограничение придется выполнять внеполосно (в коде), если вы застряли на XSD 1.0.

[Обновление. Однако см. хорошую идею XSD 1.0 о xs:unique @ sergioFC, если цель проста чтобы все x значения были уникальными в пределах data.]

Если вы можете использовать XSD 1.1, как предлагает @lexicore, это сработает. Используйте xs:assert:

  <xs:element name="data">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="point" type="ctPoint" minOccurs="4" maxOccurs="4" />
      </xs:sequence>
      <xs:assert test="count(point[x = 'count']) = 1 and
                       count(point[x = 'maxtime']) = 1"/>
    </xs:complexType>
  </xs:element>
person kjhughes    schedule 03.12.2014

Вы можете использовать xs: uniqe, который также действителен в XSD 1.0.

<xs:element name="data">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="point" type="ctPoint" minOccurs="1" maxOccurs="4" />
        </xs:sequence>
    </xs:complexType>
    <xs:unique name="myUnique">
        <!-- Select all points in data -->
        <xs:selector xpath="point" />
        <!-- The value of x of every selected point should be unique -->
        <xs:field xpath="x" />
    </xs:unique>
</xs:element>

Кроме того, для этого, я думаю, вам следует изменить minOccurs, как сказал пользователь kjhughes в своем ответе.

person sergioFC    schedule 05.12.2014
comment
Это хорошая идея и может помочь OP, однако обратите внимание, что обеспечение уникальности всех x элементов - это не то же самое, что требование наличия только одного из x элементов с определенными строковыми значениями. Например, ваш XSD допускает x = 1, x = 2, x = 3, x = 4. Также было бы запрещено x = count, x = maxtime, x = 1, x = 1. - person kjhughes; 05.12.2014
comment
@kjhughes Я думаю, что это правильно, потому что значения x ограничены в перечислении OP. - person sergioFC; 05.12.2014
comment
Хорошо, вы правы насчет x = 1, x = 2, x = 3, x = 4 из-за ограничения перечисления, о котором я забыл. Однако ваш XSD по-прежнему будет запрещать, например, x = count, x = maxtime, x = mean, x = mean. ... Но теперь, когда я перечитал требование OP, после его единственного с ограничением стоит "...", так что есть хороший шанс, что вы правы в том, что все должны быть уникальными. Хорошо, у вас есть мой +1. ;-) - person kjhughes; 05.12.2014
comment
Спасибо :) Я также дал вам +1 из-за правильного подхода к утверждениям и информации происходит. - person sergioFC; 05.12.2014