andreasmartens
andreasmartens

Reputation: 108

How can I create multiple inheritance or polymorphism in XML Schema?

I want to be able to represent two different XML structures with the same schema: One:

<polly> wibble </polly>

Two:

<polly>
  <element> foo </element>
  <element> bar </element>
  <element> baz </element>
</polly>

(in this case they're all string elements, but I'd like to be able to solve this for other types)...

What I've tried is to create a hierarchy like with a base type:

  <xsd:complexType name="polly"/>

then two subtypes, a string:

  <xsd:complexType name="polly_string">
    <xsd:complexContent>
      <xsd:extension base="tns:polly"/>
    </xsd:complexContent>
  </xsd:complexType>

and then the array type:

  <xsd:complexType name="polly_array">
    <xsd:complexContent>
      <xsd:extension base="tns:polly">
        <xsd:sequence>
          <xsd:element maxOccurs="unbounded" minOccurs="0" name="element" type="tns:polly_array_element"/>
        </xsd:sequence>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>
  <xsd:simpleType name="polly_array_element">
    <xsd:restriction base="xsd:string"/>
  </xsd:simpleType>

which I can then instantiate with:

  <xsd:element minOccurs="0" name="polly" type="tns:polly"/>

So good so far, but I can't tell it that polly_string should really be a simple type! And I can't place a restriction on it either, because it's already an extension (at least from my limited reading they're mutually exclusive).

I've mostly used vs code to do my validating, as it's more verbose than other editors, but I must admit I don't quite understand what it's telling me, hence asking here.

I've tried:

  <xsd:complexType name="polly_string">
    <xsd:complexContent>
      <xsd:extension base="tns:polly">
        <xsd:restriction base="xs:string"/>
      </xsd:extension>
    </xsd:complexContent>

but I get:

The content of 'polly_string' is invalid. Element 'restriction' is invalid, misplaced, or occurs too often.

I've tried (which wouldn't get me the whole way, but was an exploration):

  <xsd:complexType name="polly_string">
    <xsd:simpleContent>
      <xsd:extension base="tns:polly">
      </xsd:extension>
    </xsd:simpleContent>
  </xsd:complexType>

but I get:

Complex Type Definition Representation Error for type 'polly_string'. When is used, the base type must be a complexType whose content type is simple, or, only if restriction is specified, a complex type with mixed content and emptiable particle, or, only if extension is specified, a simple type. 'polly' satisfies none of these conditions.

which I think means "You can't create a simple extension of something that may be complex"?

I've tried:

  <xsd:complexType name="polly_string">
    <xsd:complexContent>
      <xsd:extension base="tns:polly"/>
      <xsd:extension base="xs:string"/>
    </xsd:complexContent>
  </xsd:complexType>

But I get:

The content of 'polly_string' is invalid. Element 'extension' is invalid, misplaced, or occurs too often.

presumably meaning "only single inheritance allowed buddy: straight to XML jail!"

I've seen some other posts with similar-looking answers, but I can't quite seem to see how to apply the solutions :-(

any kind souls able to help?

Upvotes: 1

Views: 39

Answers (1)

Michael Kay
Michael Kay

Reputation: 163577

You can't define that an element is allowed to have either a simple type or a complex type. The closest you can get is to define it with mixed content so it allows any mixture of text nodes and child elements. In XSD 1.1 you can define an additional constraint with assertions: for example, having given it a mixed content model, you can then assert xpath="exists(child::text()) ne exists(child::*)" to say that you can either have text node children or element children but not both.

Upvotes: 2

Related Questions