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).


person Simon Righley    schedule 07.05.2014    source источник
comment
Можете ли вы использовать XSD 1.1? Или вы ограничены XSD 1.0?   -  person helderdarocha    schedule 07.05.2014
comment
Отредактировано, к сожалению, только 1.0.   -  person Simon Righley    schedule 07.05.2014


Ответы (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 есть не более одного дочернего элемента любого разнообразия (если вы используете подход с вложенным выбором). .

person C. M. Sperberg-McQueen    schedule 08.05.2014
comment
Спасибо @C. М., действительно, я решил пойти с первым решением, которое вы описали. Очень содержательный ответ, очень признателен! - person Simon Righley; 09.05.2014