XML и XSD - используйте имя элемента в качестве замены xsi:type для полиморфизма

Взятие механизма 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 предположить значение 'Плоскости' при вызове элемента 'плоскостью'? Или я должен сделать явный выбор? Я был бы, точно так же, как для хранения моего дизайна DRY - если у Вас есть какие-либо другие предложения (как группы или так) - я внимательно слушаю.

5
задан Alexander Torstling 1 June 2010 в 14:21
поделиться

1 ответ

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

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

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

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

3
ответ дан 15 December 2019 в 06:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: