XSD: указать, что выбор должен иметь хотя бы один из списка, но не более одного - PullRequest
4 голосов
/ 22 ноября 2011

Это сводит меня с ума в течение нескольких часов.Я прочитал каждый соответствующий вопрос XSD по SO и остальной части Интернета, кажется, и до сих пор ответ ускользает от меня.

Мне нужна схема XML, которая требует наличия хотя бы одного из списка элементов, но каждыйэлемент может появляться только 0 или 1 раз.

Это похоже на вопрос: Конструкция XML-схемы для "любого одного или нескольких из этих элементов, но должна быть хотя бы один"

но я не смог ограничить верхний предел: я, очевидно, неправильно использую maxOccurs.

Вот где я остановился на своей схеме:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
    <xs:complexType name="Selects">
        <xs:sequence minOccurs="2" maxOccurs="4">
        <xs:choice>
        <xs:element name="aaa" minOccurs="1" maxOccurs="1"/>
        <xs:element name="bbb" minOccurs="1" maxOccurs="1"/>
        <xs:element name="ccc" minOccurs="1" maxOccurs="1"/>
        <xs:element name="ddd" minOccurs="1" maxOccurs="1"/>
        </xs:choice>
    </xs:sequence>
    </xs:complexType>
    <xs:element name="baseElement">
        <xs:complexType>
        <xs:sequence>
        <xs:element name="MyChoice" type="Selects"/>
            </xs:sequence>
    </xs:complexType>
    </xs:element>
</xs:schema>

Я пыталсяminOccurs и maxOccurs на выбор и элемент без удачи.Вот XML, который проверяет, хотя я не хочу его:

<?xml version="1.0" encoding="UTF-8"?>
<baseElement xsi:noNamespaceSchemaLocation="myTest.xsd"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <MyChoice>
        <ddd/>
        <ddd/>
    </MyChoice>
</baseElement>

Вот пример того, что я хотел бы, если это возможно:

<?xml version="1.0" encoding="UTF-8"?>
<baseElement xsi:noNamespaceSchemaLocation="myTest.xsd"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <MyChoice>
        <ddd/>
        <aaa/>
        <ccc/>
    </MyChoice>
</baseElement>

Я бы хотел, чтобыпожаловаться на множественные элементы ddd, но разрешить любой или все остальные в любом порядке.Я получаю сообщение об ошибке, если у меня только один элемент в MyChoice, так что по крайней мере что-то работает.

Что я делаю не так?Как запретить проверку нескольких одинаковых элементов?

ОБНОВЛЕНИЕ

Это было мое решение (из комментариев ниже):

На самом деле, хз: все сделали свое дело.Я поменял выбор для всех и добавил minOccurs = "0" maxOccurs = "1" для каждого элемента.С xs: all minOccurs должно быть либо 0, либо 1, а maxOccurs должно быть 1. Спасибо за вашу помощь - я в порядке!

1 Ответ

3 голосов
/ 22 ноября 2011

Просто переместите <xs:sequence minOccurs="2" maxOccurs="4"> от выбора к точке, где вы хотите использовать его дальше вниз. (вы также можете удалить значение min / max = 1, так как это то, что делает xs: choice)

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
  <xs:complexType name="Selects">
    <xs:choice>
      <xs:element name="aaa" />
      <xs:element name="bbb" />
      <xs:element name="ccc" />
      <xs:element name="ddd" />
    </xs:choice>
  </xs:complexType>
  <xs:element name="baseElement">
    <xs:complexType>
      <xs:sequence minOccurs="2" maxOccurs="4">
        <xs:element name="MyChoice" type="Selects" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

Это подтверждает следующее:

<baseElement xsi:noNamespaceSchemaLocation="myTest.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <MyChoice>
    <bbb></bbb>
  </MyChoice>
  <MyChoice>
    <ccc></ccc>
  </MyChoice>
</baseElement>

UPDATE

Я думаю, вы достигли предела того, что вы можете достичь с помощью XSD. Я не вижу, как вы можете это сделать, кроме как путем определения «версии» типа MyChoice для каждой возможной комбинации (для которой затем потребуются разные имена MyChoice1, MyChoice2 и т. Д.)

Вы также можете использовать xs: все

  <xs:complexType name="Selects">
    <xs:all minOccurs=2 maxOccurs=4>
      <xs:element name="aaa" />
      <xs:element name="bbb" />
      <xs:element name="ccc" />
      <xs:element name="ddd" />
    </xs:all>
  </xs:complexType>

но это не помешает вам иметь четыре <ddd/>

...