在XSD 1.0中-如何在xs:all内部实现xs:choice?

时间:2019-06-18 20:12:32

标签: xml xsd choice

我想指定一个不强制排序但包含选择要求的XML模式。所谓的“最佳做法”是什么?

例如,假设我希望以下两项均有效:

<foo>
  <bar>3</bar>
  <baz>tree</baz>
  <blort>
    <location>somewhere</location>
    <elevation>2000ft</elevation>
    <zing>1234567</zing>
  </blort>
</foo>

<foo>
  <baz>tree</baz>
  <blort>
    <elevation>2000ft</elevation>
    <location>somewhere</location>
    <bling>
      <name>A name</name>
      <number>7</number>
    </bling>
  </blort>
  <bar>3</bar>
</foo>

一般的“英语描述”规则大致如下:“您必须以任意顺序包括条形,底色和斑点。斑点必须包括位置,海拔高度以及正好其中之一可以是金光闪闪的,也可以是闪烁的。”

我想在使用XSD 1.0的验证解析器中对此进行解析。我的第一次天真尝试是这样的:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema 
    targetNamespace="http://my.url/Foo"
    elementFormDefault="qualified"
    xmlns="http://my.url/Foo"
    xmlns:mstns="http://my.url/Foo"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
>

<xs:complexType name="bling">
  <xs:all>
    <xs:element name="name" type="xs:string"/>
    <xs:element name="number" type="xs:decimal"/>
  </xs:all>
</xs:complexType>

<xs:complexType name="blort">
  <xs:all>
    <xs:element name="location" type="xs:string"/>
    <xs:element name="elevation" type="xs:string"/>
    <xs:choice>
      <xs:element name="zing" type="xs:string"/>
      <xs:element name="bling" type="mstns:bling"/>
    </xs:choice>
  </xs:all>
</xs:complexType>


<xs:complexType name="foo">
  <xs:all>
    <xs:element name="bar" type="xs:decimal"/>
    <xs:element name="baz" type="xs:string"/>
    <xs:element name="blort" type="mstns:blort"/>
  </xs:all>
</xs:complexType>

<xs:element name="foo" type="mstns:foo"/>

</xs:schema>

但是,那当然行不通。您不能将“选择”放在“全部”中。

我一直无法找到一种在XSD中表达我想要的内容的方法。

1 个答案:

答案 0 :(得分:1)

您可以使用 substitutionGroup 方法。

这涉及使用xs:choice属性替换substitutionGroup。因此,在您的情况下,必须将名为“ bling”的complexType转换为带有替换组bling

的名为distinctIng的单独元素
<xs:element name="bling" substitutionGroup="distinctIng">
  <xs:complexType>
    <xs:all>
      <xs:element name="name" type="xs:string"/>
      <xs:element name="number" type="xs:decimal"/>
    </xs:all>
  </xs:complexType>
</xs:element>

使其成为substitutionGroup="distinctIng"的一部分。现在,您可以将所有其他(在本例中为一个)元素放入同一个名为substitutionGroup的{​​{1}}中,例如:

distinctIng

现在唯一要做的就是用

引用基础元素。
<xs:element name="distinctIng" />  <!-- abstract base element -->
<xs:element name="zing"  substitutionGroup="distinctIng" type="xs:string" />
<xs:element name="bling" substitutionGroup="distinctIng">
  ... (code from above) ...
</xs:element>

在此示例中,是整个<xs:element ref="distinctIng" /> 替换代码:

xs:choice