5

以W3C车载XSD为例:

<schema xmlns="http://www.w3.org/2001/XMLSchema"
           targetNamespace="http://cars.example.com/schema"
           xmlns:target="http://cars.example.com/schema">

  <complexType name="Vehicle" abstract="true"/>

  <complexType name="Car">
    <complexContent>
      <extension base="target:Vehicle"/>
      ...
    </complexContent>
  </complexType>

  <complexType name="Plane">
    <complexContent>
      <extension base="target:Vehicle"/>
      <sequence>
        <element name="wingspan" type="integer"/>
      </sequence>
    </complexContent>
  </complexType>      
</schema>

,以及以下“meansOfTravel”的定义:

<complexType name="MeansOfTravel">
  <complexContent>
    <sequence>        
      <element name="transport" type="target:Vehicle"/>        
    </sequence>
  </complexContent>
</complexType>

<element name="meansOfTravel" type="target:MeansOfTravel"/>

使用此定义,您需要使用 xsi:type 指定实例的类型,如下所示:

<meansOfTravel>
  <transport xsi:type="Plane">
     <wingspan>3</wingspan>
  </transport>
</meansOfTravel>

我只想实现“类型名称”-“元素名称”映射,以便可以将其替换为

<meansOfTravel>
  <plane>
    <wingspan>3</wingspan>
  </plane>
</meansOfTravel>

到目前为止,我能做到这一点的唯一方法是明确表示:

<complexType name="MeansOfTravel">
  <sequence>        
    <choice>
      <element name="plane" type="target:Plane"/>
      <element name="car" type="target:Car"/>         
    </choice>
  </sequence>
</complexType>

<element name="meansOfTravel" type="target:MeansOfTravel"/>

但这意味着我必须在“MeansOfTravel”复杂类型中列出所有可能的子类型。如果您将元素称为“平面”,是否无法让 XML 解析器假定您的意思是“平面”?还是我必须明确做出选择?我只想让我的设计保持干燥——如果你有任何其他建议(比如团体等)——我会全力以赴。

4

1 回答 1

3

围绕这一点有一个通用的设计模式,您可以使用子类型(正如您已经在做的那样)和替换组中的元素。替换组中的元素必须是它们被替换的元素的子类型。

不幸的是,替换组元素需要定义为全局元素。所以你会有这个:

<complexType name="MeansOfTravel">
  <complexContent>
    <sequence>        
      <element ref="transport"/>
    </sequence>
  </complexContent>
</complexType>

<element name="transport" type="target:Vehicle"/>
<element name="plane" type="target:Plane" substitutionGroup="target:transport"/>

然后,在您的 XML 文档中,您可以使用:

<meansOfTravel>
    <plane>...</plane>
</meansOfTravel>

更多关于替换组的信息在这里。不,不幸的是解析器无法猜到这一点,所以你仍然必须列出元素:(虽然有一个选择的优势:模式可以通过导入外部扩展,无需修改它。无法扩展选择.

于 2010-06-01T15:21:17.283 回答