XML Schema:为什么不能都有子代?这怎么能被忽略呢?

时间:2022-06-02 17:17:19

I'm trying to create a schema for a <property> element which must have a <key> sub-element, and one of <val>, <shell> or <perl> and an optional <os> or <condition>, and the order of the sub-elements doesn't matter.

我正在尝试为一个必须具有 子元素的 元素创建一个模式,该元素必须具有 ,以及一个可选的 ,子元素的顺序无关紧要。

Here are some sample for valid <property> elements:

以下是有效 elements >的一些示例:

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

Ideally, I thought of using <xs:all> for this:

理想情况下,我想使用 来实现这个:

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

But I found out that <xs:all> can contain only <xs:element> and not <xs:choice>. Can someone explain why is it?

但我发现 只能包含 ,而不能包含 。有人能解释为什么吗? 所有>

More importantly, can someone provide a way to validate such a <property> element?

更重要的是,有人能提供一种验证此类 元素的方法吗?

I can put the three elements - <val>, <perl> and <shell> - as optional elements in the <xs:all>, but I want the schema to validate that one and only one of the three exists in the element. Can this be done?

我可以将三个元素—— ——作为 中的可选元素,但我希望模式验证这三个元素中只有一个存在于元素中。这个可以做吗?

2 个解决方案

#1


22  

I think this is a bit better, as the "choice" is now it's own element (typeFacet), but cannot be used directly as it is abstract.

我认为这更好一点,因为“选择”现在是它自己的元素(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


6  

Based on newt's comment about using substitution groups for the choice (tested with xmllint):

根据newt关于使用替代组进行选择的评论(使用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>

#1


22  

I think this is a bit better, as the "choice" is now it's own element (typeFacet), but cannot be used directly as it is abstract.

我认为这更好一点,因为“选择”现在是它自己的元素(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


6  

Based on newt's comment about using substitution groups for the choice (tested with xmllint):

根据newt关于使用替代组进行选择的评论(使用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>