Конструкция XML-схемы для «любого одного или нескольких из этих элементов, но должна быть хотя бы один» - PullRequest
22 голосов
/ 19 сентября 2008

Я пытаюсь настроить часть схемы, которая похожа на «Последовательность», где все дочерние элементы являются необязательными, но хотя бы один из элементов должен присутствовать , и их может быть больше, чем один из них.

Я попытался сделать следующее, но XMLSpy жалуется, что «Модель содержимого содержит элементы и , которые не могут быть определены однозначно."

    <xs:choice>
        <xs:sequence>
            <xs:element name="DateConstant"/>
            <xs:element name="TimeConstant"/>
        </xs:sequence>
        <xs:element name="DateConstant"/>
        <xs:element name="TimeConstant"/>
    </xs:choice>

Можно ли это сделать (и если да, то как)?

Некоторые уточнения: Я хочу разрешить только один элемент с одинаковым именем. Может быть один «DateConstant» и / или один «TimeConstant», но не два из них. Ответ Гизмо соответствует моим требованиям, но он нецелесообразен для большего количества элементов. Ответ Херста допускает два или более элемента с одинаковыми именами, которые я не хочу.

Ответы [ 3 ]

23 голосов
/ 19 сентября 2008

Попробуйте это:

<xs:choice>
  <xs:sequence>
    <xs:element name="Elem1" />
    <xs:element name="Elem2" minOccurs="0" />
    <xs:element name="Elem3" minOccurs="0" />
  </xs:sequence>
  <xs:sequence>
    <xs:element name="Elem2" />
    <xs:element name="Elem3" minOccurs="0" />
  </xs:sequence>
  <xs:element name="Elem3" />
</xs:choice>

При этом вы заставляете либо выбрать первый элемент, а затем остальное необязательно, либо второй элемент, а остальное необязательно, либо третий элемент.

Это должно делать то, что вы хотите, я надеюсь.

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

17 голосов
/ 19 сентября 2008

Согласно технической статье на MSDN под названием Понимание схемы XML на http://msdn.microsoft.com/en-us/library/aa468557.aspx#understandxsd_topic5 Вы можете воспользоваться такими ограничениями, как minOccurs для самого определения выбора (композитор):

«Использование ограничений на вхождение для композитора относится ко всей группе в целом»

(см. Более сложный пример, который использует вложенные сложные типы, и пример AuthorType)

Вы заявили о своем требовании как «должен присутствовать хотя бы один из элементов, а их может быть несколько». Таким образом, я предлагаю вам попробовать следующее:

<xs:choice minOccurs="1" maxOccurs="unbounded">
    <xs:element name="DateConstant" type="..."/>
    <xs:element name="TimeConstant" type="..."/>
</xs:choice>
2 голосов
/ 14 января 2013

@ бугор,

К сожалению, вы не поняли первоначальный вопрос. Размещение minOccurs = "1" в выборе выполняется автоматически, когда ВСЕ элементы с minOccurs = "0" содержатся в качестве параметров.

Таким образом, вы не учли «по крайней мере один», требуемый оригинальным постером, потому что ни один элемент не удовлетворяет 1 появлению двух совершенно дополнительных элементов.

Пока что я не могу найти решение этой проблемы, поскольку minOccur / maxOccur относятся к группе, в которой они определены, и НЕ относятся к общему количеству узлов. Также вы не можете использовать элемент choice для определения одного и того же именованного элемента более одного раза, или он становится «неоднозначным». Я видел некоторые примеры использования ссылок вместо элементов определенного типа, но я считаю, что это не работает синтаксический анализатор Microsoft XSD.

<xs:choice minOccurs="1" maxOccurs="1">
  <xs:sequence minOccurs="1" maxOccurs="1">
    <xs:element name="Elem1" minOccurs="1" maxOccurs="1" />
    <xs:element name="Elem2" minOccurs="0" maxOccurs="1" />
  </xs:sequence>
  <xs:sequence >
    <xs:element name="Elem2" minOccurs="1" maxOccurs="1" />
  </xs:sequence>
</xs:choice>

Здесь вы можете видеть, что либо у вас есть первая последовательность (которая ДОЛЖНА иметь Elem1, но может иметь Elem2 по выбору), либо у вас есть вторая последовательность (которая ДОЛЖНА иметь Elem2).

Следовательно, теперь у вас есть «один или несколько» из этих 2 элементов. Конечно, это становится экспоненциально сложнее, чем больше у вас вариантов, так как вам нужно предоставить дополнительные варианты для всех возможных комбинаций.

...