XML-схема обеспечивает существование элемента

Имеют следующую XML-схему (XSD 1.0):

<xs:element name="Fruits">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="Fruit_id" type="xs:int" minOccurs="1" maxOccurs="1"/>
      <xs:choice minOccurs="1" maxOccurs="1">
        <xs:element ref="Apple" minOccurs="1" maxOccurs="1"/>
        <xs:element ref="Banana" minOccurs="1" maxOccurs="1"/>
        <xs:sequence>
          <xs:element ref="Cherry" minOccurs="0" maxOccurs="1"/>
          <xs:element ref="Durian" minOccurs="0" maxOccurs="1"/>
          <xs:element ref="Elderberry" minOccurs="0" maxOccurs="1"/>
          <xs:element ref="Fig" minOccurs="0" maxOccurs="1"/>
        </xs:sequence>
      </xs:choice>
    </xs:sequence>
  </xs:complexType>
</xs:element>

Проблема, с которой я сталкиваюсь, заключается в том, что эта схема позволяет Fruits состоять только из Fruit_idи я хотел бы обеспечить по крайней мере один фрукт (т.е. Apple или же Banana или же Cherry или же Durian или же Elderberry или же Fig) присутствовать в Fruits, Я попытался изменить вышеприведенное на следующее (короче говоря, заменить sequence с choice и изменить соответствующие minOccurs в 1):

<xs:element name="Fruits">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="Fruit_id" type="xs:int" minOccurs="1" maxOccurs="1"/>
      <xs:choice minOccurs="1" maxOccurs="1">
        <xs:element ref="Apple" minOccurs="1" maxOccurs="1"/>
        <xs:element ref="Banana" minOccurs="1" maxOccurs="1"/>
        <xs:choice minOccurs="1" maxOccurs="4">
          <xs:element ref="Cherry" minOccurs="1" maxOccurs="1"/>
          <xs:element ref="Durian" minOccurs="1" maxOccurs="1"/>
          <xs:element ref="Elderberry" minOccurs="1" maxOccurs="1"/>
          <xs:element ref="Fig" minOccurs="1" maxOccurs="1"/>
        </xs:choice>
      </xs:choice>
    </xs:sequence>
  </xs:complexType>
</xs:element>

который, действительно, заставляет по крайней мере один из вышеупомянутых плодов существовать в Fruits, но это позволяет Cherry, Durian, Eldeberry, а также Figсоответственно, появиться до четырех раз в Fruitsв то время как мое намерение состоит в том, чтобы каждому из них, соответственно, было позволено существовать в Fruits максимум один раз (вот почему я пытался с maxOccurs="4" в (вложенный) choice элемент).

1 ответ

Решение

У вас есть несколько вариантов, все с некоторыми недостатками.

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

<xs:choice>
  <xs:sequence>
    <xs:element ref="Cherry"/>
    <xs:element ref="Durian" minOccurs="0"/>
    <xs:element ref="Elderberry" minOccurs="0"/>
    <xs:element ref="Fig" minOccurs="0"/>
  </xs:sequence>        
  <xs:sequence>
    <xs:element ref="Durian"/>
    <xs:element ref="Elderberry" minOccurs="0"/>
    <xs:element ref="Fig" minOccurs="0"/>
  </xs:sequence>        
  <xs:sequence>
    <xs:element ref="Elderberry"/>
    <xs:element ref="Fig" minOccurs="0"/>
  </xs:sequence>        
  <xs:sequence>
    <xs:element ref="Fig"/>
  </xs:sequence>    
</xs:choice>

(Я пропустил значения по умолчанию minOccurs и maxOccurs, чтобы разница между minOccurs="0" и minOccurs="1" была больше.)

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

Вы могли бы пойти с вашим вложенным дизайном выбора и указать, на уровне приложения, что единственное, что имеет значение, это наличие данного фрукта, а не количество раз, которое он присутствует, поэтому <Fruits><Cherry/><Cherry/><Fig/></Fruits> семантически такой же, как <Fruits><Cherry/><Fig/></Fruits>, Это не так уж плохо, если на самом деле они являются пустыми элементами, но если они имеют длинное сложное содержимое (и особенно если два разных экземпляра Cherry могут давать разную, т. Е. Противоречивую) информацию, это может показаться слишком опасным или запутанным.

Вы можете добавить слой проверки Schematron и добавить утверждение, что у Fruits есть хотя бы один дочерний элемент (если вы остаетесь с первоначальным эскизом) или что у Fruit есть не более одного дочернего элемента любого сорта (если вы используете подход с вложенным выбором),

Другие вопросы по тегам