XSD и полиморфизм - PullRequest
       20

XSD и полиморфизм

4 голосов
/ 16 октября 2008

Я немного повторяю этот вопрос в первый раз, когда он был задан неправильно.

У меня есть это:

<xsd:complexType name="A">
        <xsd:sequence>
            <xsd:element name="options" type="options"/>
        </xsd:sequence>
</xsd:complexType>

<xsd:complexType name="B">  
    <xsd:complexContent>
            <xsd:element name="options" type="ex_options"/>
    </xsd:complexContent>
</xsd:complexType>

<xsd:complexType name="options">
    <xsd:sequence>
        ...some options
    </xsd:sequence>
</xsd:element>

<xsd:complexType name="ex_options">
    <xsd:complexContent>
         <xsd:extension base="options">
             <xsd:sequence>
              ...some more options
              </xsd:sequence>
          </xsd:extension>
     </xsd:complexContent>
 </xsd:element>

Так что в основном у меня есть класс А с внутренним классом опций Класс B наследуется от класса A, и я хочу, чтобы B.options наследовали от A.options, так что когда мы делаем веб-сервисы, нам нужно только передать a, а когда мы вызываем getOptions, он вернет нужный объект B.options. В настоящее время с тем, как стоит xsd, я получаю сообщение о том, что в группе моделей появляется несколько элементов с опциями имен разных типов. Ошибки в типе B.

Ответы [ 3 ]

4 голосов
/ 08 ноября 2008

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

<xsd:complexType name="B">  
      <xsd:complexContent>
                <xsd:element name="options" type="ex_options"/>
      </xsd:complexContent>
</xsd:complexType>

<xsd:complexType name="options">
      <xsd:sequence>
              ...some options
      </xsd:sequence>
</xsd:element>

<xsd:complexType name="ex_options">
      <xsd:complexContent>
             <xsd:extension base="options">
                   <xsd:sequence>
                        ...some more options
                    </xsd:sequence>
              </xsd:extension>
       </xsd:complexContent>
</xsd:element>

и затем "украсить" ваш элемент экземпляра как

<options xsi:type="ex_options"> ...     (this will work)

или

<options xsi:type="options"> ...     (I think you can do this as long as the base xsi:type is not abstract)

Если окажется, что вы не можете украсить основанием xsi:type, тогда вы всегда можете "обмануть", создав пустой базовый тип, а затем расширяя путем тщательной конструкции, чтобы получить два желаемых формата.

См. этот пост для более подробной информации и ссылок.

0 голосов
/ 27 июля 2010

Вы также можете использовать ограничение, а не расширение, но это не лучшее решение, потому что ограничение удаляет все базовые определения. Лучший вариант - использовать xsi: type во время выполнения (в экземплярах XML-элементов), как описано в другом ответе.
Еще один пример использования xsi: type приведен здесь: http://www.xfront.com/ElementHierarchy.html

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 <!-- Root element -->
 <xsd:element name="root" type="B"/>

 <!-- Base abstract type -->
 <xsd:complexType name="A" abstract="true">
  <xsd:sequence>
   <!-- Option that we will override -->
   <xsd:element name="options" type="options"/>
  </xsd:sequence>
 </xsd:complexType>

 <!-- Derived type -->
 <xsd:complexType name="B">
  <xsd:complexContent>
   <!--Overriding -->
   <xsd:restriction base="A">
    <xsd:sequence>
     <xsd:element name="options" type="ex_options"/>
    </xsd:sequence>
   </xsd:restriction>
  </xsd:complexContent>
 </xsd:complexType>

 <!-- Base included class -->
 <xsd:complexType name="options">
  <xsd:sequence>
   <xsd:element name="baseOption"/>
  </xsd:sequence>
 </xsd:complexType>

 <!-- Overriding of included class -->
 <xsd:complexType name="ex_options">
  <xsd:complexContent>
   <xsd:restriction base="options">
    <xsd:sequence>
     <xsd:element name="overridedOption"/>
    </xsd:sequence>
   </xsd:restriction>
  </xsd:complexContent>
 </xsd:complexType>
</xsd:schema>

В псевдо CiXML это будет что-то вроде:

{
  B root;

  abstract class A
  {
    options options;
  }

  class B override A
  {
    ex_options options;
  }

  class options
  {
    empty baseOption;
  }

  class ex_option override options
  {
    empty overridedOption
  }
}

Вот пример XML:

<?xml version="1.0" encoding="UTF-8"?>
<root xsi:noNamespaceSchemaLocation="polymorphism.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <options>
    <overridedOption/>
  </options>
</root>
0 голосов
/ 16 октября 2008

Вы можете сделать последовательность options открытой, чтобы вы могли иметь любое количество параметров, а затем проверить существующие параметры на основе значения атрибута. Например, в следующей схеме список options имеет атрибут type либо A, либо B, указывающий, какие параметры должны быть перечислены в действительности:

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

  <!-- Elements for document structure. -->
  <!-- This section is just for validating my example file to -->
  <!-- demonstrate the schema. -->
  <xs:element name="root">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="elementA" type="A" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element name="elementB" type="A" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>



  <!-- The important part of the schema. -->
  <!-- Types -->
  <!-- A has options of type options. -->
  <xs:complexType name="A">
    <xs:sequence>
      <xs:element name="options" type="options"/>
    </xs:sequence>
  </xs:complexType>

  <!-- Options specifies a options with a type attribute specifying which options will be available. -->
  <xs:complexType name="options">
    <xs:sequence>
      <xs:element name="option" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
    <xs:attribute name="type" use="optional" default="A">
      <xs:simpleType>
        <xs:restriction base="xs:string">
          <xs:enumeration value="A"/>
          <xs:enumeration value="B"/>
        </xs:restriction>
      </xs:simpleType>
    </xs:attribute>
  </xs:complexType>

</xs:schema>

Вот пример XML для этой схемы.

<?xml version="1.0" encoding="utf-8"?>
<root xmlns="http://tempuri.org/XMLSchema.xs">
  <elementA>
    <options type="A">
      <option>Test-A</option>
      <option>Test2-A</option>
    </options>
  </elementA>
  <elementB>
    <options type="B">
      <option>Test-B</option>
      <option>Test2-B</option>
      <option>Test3-B</option>
      <option>Test4-B</option>
    </options>
  </elementB>
</root>
...