XML и XSD - использовать имя элемента в качестве замены xsi: type для полиморфизма - PullRequest
5 голосов
/ 01 июня 2010

Взяв в качестве примера автомобиль XSD W3C:

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

Я просто хотел бы получить отображение 'name of type' - 'name of element', чтобы его можно было заменить просто

<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 предполагать, что вы имеете в виду «плоскость», если вы называете элемент «плоскостью»? Или я должен сделать выбор явным? Я просто хотел бы сохранить свой дизайн СУХИМ - если у вас есть какие-либо другие предложения (например, группы или около того) - я весь слух.

1 Ответ

3 голосов
/ 01 июня 2010

Вокруг этого есть общий шаблон проектирования, вы можете использовать подтипы (как вы уже делаете) и элементы в группе подстановки. Элементы в группе замещения должны быть подтипа элемента, который они заменяют.

К сожалению, элементы группы замещения должны быть определены как глобальные элементы. Таким образом, у вас будет это:

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

Подробнее о группах замещения здесь . И нет, к сожалению, синтаксический анализатор не может догадаться об этом, поэтому вам все равно придется перечислить элементы :( Однако у выбора есть одно преимущество: схема может быть расширена извне, импортировав ее без изменения. .

...