XML 和 XSD - 使用元素名称代替 xsi:type 来实现多态性 [英] XML and XSD - use element name as replacement of xsi:type for polymorphism

查看:7
本文介绍了XML 和 XSD - 使用元素名称代替 xsi:type 来实现多态性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以W3C车载XSD为例:

Taking the W3C vehicle XSD as an example:

<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"的定义:

, and the following definition of 'meansOfTravel':

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

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

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

With this definition you need to specify the type of your instance using xsi:type, like this:

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

我只想实现一个类型名称"-元素名称"映射,以便可以将其替换为只是

I would just like to acheive a 'name of type' - 'name of element' mapping so that this could be replaced with just

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

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

The only way I could do this until now is by making it explicit:

<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 解析器假定您的意思是平面"?还是我必须明确做出选择?我只想让我的设计保持干燥 - 如果您有任何其他建议(如团体等) - 我会全力以赴.

But this means that I have to list all possible sub-types in the 'MeansOfTravel' complex type. Is there no way of making the XML parser assume that you mean a 'Plane' if you call the element 'plane'? Or do I have to make the choice explicit? I would just like to keep my design DRY - if you have any other suggestions (like groups or so) - i am all ears.

推荐答案

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

There is a common design pattern around this, you can use sub-types (as you are already doing), and elements in a substitution group. Elements in the substitution group have to be of a sub-type of the element they are substituted for.

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

Unfortuntaly, substitution group elements need to be defined as global elements. So you would have this:

<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 文档中,您可以使用:

Then, in your XML document you can use:

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

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

More info on substitution groups here. And no, unfortunately the parser cannot guess this, so you still have to list the elements :( There is one advantage over a choice though: the schema can be extended externally, by importing it, without modifying it. The choice could not be extended.

这篇关于XML 和 XSD - 使用元素名称代替 xsi:type 来实现多态性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆