Схема XML: почему <xs: all> не может иметь <choice>детей? и как это можно обойти? - PullRequest
17 голосов
/ 23 апреля 2009

Я пытаюсь создать схему для элемента <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>, но я хочу, чтобы схема проверяла, что один и только один из трех существует в элементе , Можно ли это сделать?

Ответы [ 2 ]

22 голосов
/ 23 апреля 2009

Я думаю, что это немного лучше, поскольку «выбор» теперь является собственным элементом (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>
7 голосов
/ 23 апреля 2009

На основании комментария Ньютона об использовании групп замещения для выбора (проверено с помощью 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...