Подтвердить что ты не робот

XML-схема. Почему у <xs: all> есть <выбоp> детей? и как это можно обойти?

Я пытаюсь создать схему для элемента <property>, который должен иметь подэлемент <key>, и один из <val>, <shell> или <perl> и необязательный <os> или <condition>, а порядок подэлементов не имеет значения.

Вот пример для действительных элементов <property>:

<property>
  <key>A</key>
  <val>b</val>
</property>

<property>
  <key>A</key>
  <val>b</val>
  <os>Windows</os>
</property>

<property>
  <condition>a == 1</condition>
  <key>A</key>
  <perl>1+1</perl>
  <os>unix</os>
</property>

В идеале я думал об использовании <xs:all> для этого:

<xs:element name="property">
  <xs:complexType>
    <xs:all>
      <xs:element name="key" type="xs:string" />
      <xs:choice>
        <xs:element name="val" type="xs:string" />
        <xs:element name="perl" type="xs:string" />
        <xs:element name="shell" type="xs:string" />
      </xs:choice>
      <xs:element name="os" type="xs:string" minOccurs="0" />
      <xs:element name="condition" type="xs:string" minOccurs="0" />
    </xs:all>
  </xs:complexType>
</xs:element>

Но я обнаружил, что <xs:all> может содержать только <xs:element>, а не <xs:choice>. Может кто-нибудь объяснить, почему?

Что еще более важно, может ли кто-нибудь предоставить способ проверки такого элемента <property>?

Я могу поместить три элемента - <val>, <perl> и <shell> - в качестве необязательных элементов в <xs:all>, но я хочу, чтобы схема проверяла, что одна и только одна из трех существует в элементе, Это можно сделать?

4b9b3361

Ответ 1

Я думаю, что это немного лучше, поскольку "выбор" теперь является его собственным элементом (typeFacet), но не может использоваться напрямую, поскольку он является абстрактным.

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="property">
    <xs:complexType>
      <xs:all>
        <xs:element name="key" type="xs:string" />
        <xs:element ref="typeFacet" />
        <xs:element name="os" type="xs:string" minOccurs="0" />
        <xs:element name="condition" type="xs:string" minOccurs="0" />
      </xs:all>
    </xs:complexType>
  </xs:element>

  <xs:element name="typeFacet" abstract="true" />
  <xs:element name="val" type="xs:string"   substitutionGroup="typeFacet" />
  <xs:element name="perl" type="xs:string" substitutionGroup="typeFacet" />
  <xs:element name="shell" type="xs:string" substitutionGroup="typeFacet" />
</xs:schema>

Ответ 2

Основываясь на комментариях нового пользователя об использовании подстановочных групп для выбора (протестированных с помощью xmllint):

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="property">
    <xs:complexType>
      <xs:all>
        <xs:element name="key" type="xs:string" />
        <xs:element ref="val"/>
        <xs:element name="os" type="xs:string" minOccurs="0" />
        <xs:element name="condition" type="xs:string" minOccurs="0" />
      </xs:all>
    </xs:complexType>
  </xs:element>

  <xs:element name="val" type="xs:string"/>
  <xs:element name="perl" type="xs:string" substitutionGroup="val" />
  <xs:element name="shell" type="xs:string"  substitutionGroup="val" />
</xs:schema>