Reputation: 6547
I believed to have understand everything in this article, but it seems that there is still some work for me.
If I have a simple inheritance tree in my classes:
A (abstract)
^
B
^
C
And I want to have a simple list of objects in my xml as followes:
<mylist>
<B>lalala</B>
<C>fofofo</C>
<C>fofofo</C>
<C>fofofo</C>
<C>fofofo</C>
<B>lalala</B>
</mylist>
It doesn't seem to work when I try to validate this scheme against:
<xs:schema>
<xs:complexType name="A" abstract="true">
<xs:element name="text" type="xs:string"/>
</xs:complexType>
<xs:complexType name="B">
<xs:complexContent>
<xs:extension base="A"/>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="C">
<xs:complexContent>
<xs:extension base="B"/>
</xs:complexContent>
</xs:complexType>
<xs:element name="mylist>
<xs:sequence maxOccurs="unbounded">
<xs:element name="A" type="A"/>
</xs:sequence>
</xs:element>
</xs:schema>
Remember, this is just pseudo code for the sake of short xmls without a lot of namespaces.
Why does a validator tell me (notepad++ for example) that it is still expecting an
<A>
and not a<B>
or a<C>
?
Upvotes: 0
Views: 125
Reputation: 25054
You're getting close. But you're conflating element names with type names. Types B and C are substitutable for type A, but you haven't declared any elements named B and C at all, let alone declared them and made them substitutable for element A.
The following XML instance is valid against a corrected version of your schema:
<mylist xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="Mamix.xsd">
<A xsi:type="B"><text>lalala</text></A>
<A xsi:type="C"><text>fofofo</text></A>
<A xsi:type="C"><text>fofofo</text></A>
<A xsi:type="C"><text>fofofo</text></A>
<A xsi:type="C"><text>fofofo</text></A>
<A xsi:type="B"><text>lalala</text></A>
</mylist>
If you want to allow elements B and C instead, declare them with appropriate types and specify that they are substitutable for element A (which must be a top-level element for this to be possible). Your schema will look like this:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="A" abstract="true">
<xs:sequence>
<xs:element name="text" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="B">
<xs:complexContent>
<xs:extension base="A"/>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="C">
<xs:complexContent>
<xs:extension base="B"/>
</xs:complexContent>
</xs:complexType>
<xs:element name="A" type="A"/>
<xs:element name="B" type="B" substitutionGroup="A"/>
<xs:element name="C" type="C" substitutionGroup="A"/>
<xs:element name="mylist">
<xs:complexType>
<xs:sequence maxOccurs="unbounded">
<xs:element ref="A"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Against this schema, the following instance (modified from your original XML by adding the 'text' element your declaration for 'A' requires) is valid:
<mylist xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="Mamix.xsd">
<B><text>lalala</text></B>
<C><text>fofofo</text></C>
<C><text>fofofo</text></C>
<C><text>fofofo</text></C>
<C><text>fofofo</text></C>
<B><text>lalala</text></B>
</mylist>
Upvotes: 1