2008-10-16 2 views
4

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

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

<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, так что, когда мы делать webservices нам нужно только передать a, и когда мы вызываем getOptions, он вернет правильный объект B.options. В настоящее время с тем, как стоит xsd, я получаю сообщение о том, что в группе модели появляются несколько элементов с параметрами имени с разными типами. Ошибки находятся в типе B.

+0

Ваш пример XSD не является корректным (исключая ... некоторые варианты ввода). Я предположил, что это пример того, что вы пробовали. Прочитав ваш ответ ниже, я получаю его сейчас. то, что вам кажется нужным, это два класса, где B расширяет A, а содержимое B расширяет содержимое A. – 2008-10-16 16:48:19

ответ

0

Вы можете сделать последовательность 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> 
4

Просто придерживайтесь ж/элементов типа B, а затем использовать затем украсить элементы документа, например, как описано ниже ж/соответствующий XSI: значение атрибута типа


<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: типа, то вы всегда можете «обмануть», создав пустой базовый тип и затем , расширяя тщательную конструкцию, чтобы достичь двух желаемых форматов.

См. this post для уточнения & ссылки.

0

Вы также можете использовать ограничение, а не расширение, но это не лучшее решение, поскольку ограничение удаляет все определения базы. Лучше всего использовать xsi: type во время выполнения (в XML-экземплярах элементов), как описано в другом ответе.
Еще один пример использования XSI: тип здесь: 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> 
Смежные вопросы