Nevermind, I think I solved it.
I missed the substitution group relation between the abstract types and
the head. I just added substitutionGroup="shape" to fgshape and bgshape
and now it works.
I guess I just missed it as I was relying too much on inheritance. I
probably figured the hierarchy alone was enough for <eraseShape> to
accept <cloud>, as you would expect in OOP, so I didn't bother to apply
them to the abstract types.
Thanks for being my rubber duck ;)
Erik
Erik van Zijst wrote:[color=blue]
> I'm having trouble translating my object inheritance models to xmlschema
> and have illustrated this in the attached example xsd and xml.
>
> In my example I have a canvas for drawing a new painting and the xsd
> contains the instructions for drawing this painting. According to
> instructor Bob, a painting constists of two basic parts: background and
> foreground. An object is either a background or foreground object.
> In the final stage, Bob removes objects that turned out ugly. This can
> be any type of object.
>
> The schema defines an abstract type "shape" which "fgshape" and gbshape"
> inherit from. It uses substitutiongroups with head "shape".
> <drawBackground> only accepts background shapes, <drawForeground> only
> accepts foreground shapes, while <eraseShapes> accepts everything.
>
> The problem is that the painting as defined in painting.xml is not valid
> according to the schema, because <eraseShapes> expects an element of
> type <shape>, rather than <cloud> or its substitutiongroup <fgshape>.
> The error xmlbeans gives is:
> Validation error at line: 12: Expected element
> 'shape@http://prutser.cx/schemas/painting' instead of
> 'cloud@http://prutser.cx/schemas/painting' here in element
>
eraseShapes@http://prutser.cx/schemas/painting
>
> In an OO programming language this is not a problem. Cloud extends
> fgshape, while fgshape extends shape, so you'll have no problem passing
> a cloud instance to eraseShapes.
>
> How does one tackle this problem? Am I using substitutionGroups
> incorrectly? I do want to be able to use the names of the concrete
> elements, rather than <shape type="cloud" color="white"
> cloudtype="cumulunimbus"/> if that's possible.
>
> cheers,
> Erik van Zijst
>
>
> ------------------------------------------------------------------------
>
> <?xml version="1.0" encoding="UTF-8"?>
> <painting xmlns="http://prutser.cx/schemas/painting"
> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
>
> <drawBackground>
> <cloud color="white" cloudtype="cumulunimbus"/>
> </drawBackground>
> <drawForeground>
> <tree color="green" height="22"/>
> </drawForeground>
> <eraseShapes>
> <cloud color="white" cloudtype="cumulunimbus"/>
> </eraseShapes>
> </painting>
>
>
> ------------------------------------------------------------------------
>
> <?xml version="1.0" encoding="UTF-8"?>
> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
> targetNamespace="http://prutser.cx/schemas/painting"
> xmlns="http://prutser.cx/schemas/painting"
> xmlns:tns="http://prutser.cx/schemas/painting"
> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
>
> <xs:element name="painting">
> <xs:complexType>
> <xs:sequence>
> <xs:element ref="drawBackground"/>
> <xs:element ref="drawForeground"/>
> <xs:element ref="eraseShapes"/>
> </xs:sequence>
> </xs:complexType>
> </xs:element>
>
> <xs:element name="drawBackground">
> <xs:complexType>
> <xs:sequence>
> <xs:element ref="bgshape" minOccurs="1" maxOccurs="unbounded"/>
> </xs:sequence>
> </xs:complexType>
> </xs:element>
>
> <xs:element name="drawForeground">
> <xs:complexType>
> <xs:sequence>
> <xs:element ref="fgshape" minOccurs="1" maxOccurs="unbounded"/>
> </xs:sequence>
> </xs:complexType>
> </xs:element>
>
> <xs:element name="eraseShapes">
> <xs:complexType>
> <xs:sequence>
> <xs:element ref="shape" minOccurs="1" maxOccurs="unbounded"/>
> </xs:sequence>
> </xs:complexType>
> </xs:element>
>
> <xs:element name="shape" type="shape-type" abstract="true"/>
> <xs:complexType name="shape-type" abstract="true">
> <xs:attribute name="color" type="xs:string" use="required"/>
> <xs:attribute name="preferredBrush" type="xs:string" use="optional"/>
> </xs:complexType>
>
> <xs:element name="bgshape" type="bgshape-type" abstract="true"/>
> <xs:complexType name="bgshape-type" abstract="true">
> <xs:complexContent>
> <xs:extension base="shape-type"/>
> </xs:complexContent>
> </xs:complexType>
>
> <xs:element name="cloud" type="cloud-type" substitutionGroup="bgshape"/>
> <xs:complexType name="cloud-type">
> <xs:complexContent>
> <xs:extension base="bgshape-type">
> <xs:attribute name="cloudtype" type="xs:string" use="required"/>
> </xs:extension>
> </xs:complexContent>
> </xs:complexType>
>
> <xs:element name="fgshape" type="fgshape-type" abstract="true"/>
> <xs:complexType name="fgshape-type" abstract="true">
> <xs:complexContent>
> <xs:extension base="shape-type"/>
> </xs:complexContent>
> </xs:complexType>
>
> <xs:element name="tree" type="tree-type" substitutionGroup="fgshape"/>
> <xs:complexType name="tree-type">
> <xs:complexContent>
> <xs:extension base="fgshape-type">
> <xs:attribute name="height" type="xs:int" use="optional"/>
> </xs:extension>
> </xs:complexContent>
> </xs:complexType>
>
> </xs:schema>[/color]