Как определить альтернативные структуры XML в схеме XSD? - PullRequest
4 голосов
/ 08 июня 2011

Как вы определяете альтернативные структуры XML в схеме xsd?Например, следующие структуры будут необязательными:

<a>
  <b/>
  <c>
    <d/>
  </c>
</a>

и

<a>
  <c>
    <e/>
  </c>
</a>

В первом случае должен быть элемент "b", если элемент "d" будет найден подэлемент "с".Во втором случае НЕТ элемента "b" будет разрешен, если в "c" будет "e"Поэтому я ищу решение такого рода:

<xsd:element name="a">
    <xsd:complexType>
        <xsd:all>

(

            <xsd:element name="b" type="whatever"/>
            <xsd:element name="c">
                <xsd:complexType>
                    <xsd:all>
                        <xsd:element name="d" type="whatever"/>
                    </xsd:all>
                </xsd:complexType>
            </xsd:element> )

) ИЛИ (

            <xsd:element name="c">
                <xsd:complexType>
                    <xsd:all>
                        <xsd:element name="e" type="whatever"/>
                    </xsd:all>
                </xsd:complexType>
            </xsd:element>

)

        </xsd:all>
    </xsd:complexType>
</xsd:element>

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

Ответы [ 2 ]

1 голос
/ 10 июня 2011

Я немного заимствую ответ thecolour.Что я имел в виду, что я не хотел, чтобы моя структура выбора находилась внутри элемента.

С ответом thecolour будет работать такой документ:

<?xml version="1.0"?>
<Root>
<structure>
<a1>
<b>jkhgjhg</b>
<c>
<d>asdf</d>
</c>
</a1>
</structure>
</Root>

Однако следующая схема работаеттак, как я хочу (у ответа thecolour есть и этот дополнительный элемент структуры). Я пропускаю это.):

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns="http://NS.Schema1" targetNamespace="http://NS.Schema1" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="Root">
    <xs:complexType>
       <xs:choice minOccurs="1" maxOccurs="1">
          <xs:sequence>
             <xs:element name="b" type="xs:string" />
             <xs:element name="c">
                <xs:complexType>
                   <xs:all>
                      <xs:element name="d" type="xs:string" />
                   </xs:all>
                </xs:complexType>
             </xs:element>
          </xs:sequence>
          <xs:sequence>
             <xs:element name="c">
                <xs:complexType>
                   <xs:all>
                      <xs:element name="e" type="xs:string" />
                   </xs:all>
                </xs:complexType>
             </xs:element>
          </xs:sequence>
       </xs:choice>
    </xs:complexType>
  </xs:element>
</xs:schema>

У этого недостатка есть то, что в первом выборе «b» и «c»«элементы должны быть в таком порядке.Я не знаю, почему вы не можете иметь индикатор «все» внутри «выбора».Возможно, из-за того, как синтаксический анализатор схем работает внутренне ???

С этим XML-документом схемы вот так:

<?xml version="1.0"?>
<Root>
<b>jkhgjhg</b>
<c>
<d>asdf</d>
</c>
</Root>
1 голос
/ 09 июня 2011

Решением этой проблемы является определение двух сложных типов для представления каждого «состояния» вашей структуры. Каждый сложный тип будет применять различные ограничения для вложенных элементов внутри. Затем вы можете просто сгруппировать два сложных типа как элементы под xs: choice

Что-то вроде

<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns="http://NS.Schema1" targetNamespace="http://NS.Schema1" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="Root">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="structure">
          <xs:complexType>
            <xs:choice minOccurs="1" maxOccurs="1">
              <xs:element name="a1" type="a1" />
              <xs:element name="a2" type="a2" />
            </xs:choice>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:complexType name="a1">
    <xs:sequence>
      <xs:element name="b" type="xs:string" />
      <xs:element name="c">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="d" type="xs:string" />
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="a2">
    <xs:sequence>
      <xs:element name="c">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="e" type="xs:string" />
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:sequence>
  </xs:complexType>
</xs:schema>

Однако нельзя иметь одинаковое имя корневого элемента для обоих сложных типов.

...