users@jaxb.java.net

Re: <xsd:extension> causes validation error

From: Filip Rindler <filip.rindler_at_gmx.de>
Date: Sat, 07 Jun 2003 10:56:12 +0200

Pete,

at first I want to thank you a lot for providing all this information.
However, I don't think I'm using polymorphism at all (I tried that before,
but it didn't work for reasons that are clear to me now after your
explanation). Look at my schema:
It says <xsd:element name="matrix" type="Matrix2DGrid" />, NOT <xsd:element
name="matrix" type="Matrix" /> (although that's what I want to have some
time into the future). So there can only be a Matrix2DGrid in the <matrix>
element and that's exactly what's there. The only thing is that Matrix2DGrid
should derive the "className" field from the Matrix complex type. No
polymorphism involved, just extension. However, while JAXB generates classes
that exactly reflect that (XMLBMatrix2DGrid has setClassName() and
getClassName() methods as expected; XMLBMatrix2DGrid is my JAXB-generated
class corresponding to the Matrix2DGrid complex type), I get a validation
error when unmarhalling saying the "className" attribute is not valid in the
<matrix> element, which is strange as <matrix> is always of type
Matrix2DGrid. And Matrix2DGrid should have gotten that field from its
supertype Matrix. I just don't get while JAXB can marshall the stuff, but
not unmarshall it any more. This sounds like a bug to me, but I don't
know...

Fil


----- Original Message -----
From: "Pete Hendry" <peter.hendry_at_capeclear.com>
To: <JAXB-INTEREST_at_JAVA.SUN.COM>
Sent: Saturday, June 07, 2003 7:54 AM
Subject: Re: <xsd:extension> causes validation error


> Filip,
>
> I was referring to the requirement to have xsi:type in the *instance
> document*, not the schema. From reading this group I believe that JAXB
> does not currently support polymorphism of complex types (I may be
> wrong). Instead you have to use substitution groups (a very strange
> implementation order to me as 1) this will likely result in poorer
> interop as not many other toolkits have gone to the trouble of
> implementing the little understood concept on substitution groups, and
> 2) schema complexType extension maps so nicely to java type extension
> and is easy to understand for java developers).
>
> Leaving this aside, it is required in an instance document, when using
> polymorphic types, that the polymorphic instances have xsi:type
> information. As an example, if we have
>
> <complexType name="B">
> <sequence>
> <element name="b" type="string"/>
> </sequence>
> </complexType>
>
> <complexType name="D">
> <complexContent>
> <restriction base="tns:B">
> <sequence>
> <element name="d" type="string"/>
> </sequence>
> </restriction>
> </complexContent>
> </complexType>
>
> <element name="E">
> <complexType>
> <sequence>
> <element name="e" type="tns:B"/>
> </sequence>
> </complexType>
> </element>
>
> Then the following is valid
>
> <tns:E>
> <tns:e>
> <tns:b>hello</tns:b>
> </tns:e>
> </tns:E>
>
> but this is not
>
> <tns:E>
> <tns:e>
> <tns:b>hello</tns:b>
> <tns:d>there</tns:d>
> </tns:e>
> </tns:E>
>
> This is not valid because a validating parser is expecting an instance
> of "B" and "d" is not a valid element of "B". However, this is valid
>
> <tns:E>
> <tns:e xsi:type="tns:D"> <!-- ** xsi:type added -->
> <tns:b>hello</tns:b>
> <tns:d>there</tns:d>
> </tns:e>
> </tns:E>
>
> because now the parser knows to validate the content of "e" using the
> schema type "D" rather than "B". The parser will also check that "D" is
> a valid extension of "B". Without the type information the parser cannot
> know anything about the content except it is of type "B". It could be
> argued in this case that the parser could search the subtypes of "B" and
> work out that "D" would be valid. However, what if there are multiple
> subtypes of "B" and more than one of them has an element "d"?
>
> I don't think you can solve this with JAXB at the moment because it
> doesn't support this kind of polymorphism (or does it?). But when it
> does it will have to write out the xsi:type information for any derived
> types.
>
> Pete
>
> Filip Rindler wrote:
>
> >Hi!
> >
> >I'm sorry, but I don't see the problem. To me as a Java programmer, it
seems
> >that if i use the <xsd:extension> tag, it will take all the properties
from
> >the supertype and put them in the subtype. And this is exactly what JAXB
is
> >doing - it generates setClassName() for XMLBMatrix2DGrid (JAXB-generated
> >class for Matrix2DGrid complex type) as well. This also is in the schema:
> >
> ><xsd:element name="mtxfile" type="MTXFile">
> ></xsd:element>
> >
> ><xsd:complexType name="MTXFile">
> > <xsd:all>
> > <xsd:element name="minVersion" type="xsd:int" />
> > <xsd:element name="matrix" type="Matrix2DGrid" /> <---
> >there is a type (?)
> > <xsd:element name="parameters" type="PropertyTable" />
> > </xsd:all>
> ></xsd:complexType>
> >
> >I'm not too experienced with XML so maybe you could do me the favor of
> >telling me what to change...
> >
> >Thanks in advance!
> >
> >Filip Rindler
> >
> >
> >
> >
> >>The problem is that there is no xsi:type information on the matrix
> >>element. When using polymorphism in this way in schema the xsi:type
> >>attribute is required to tell the parser that the type of the element is
> >>not the type it will find in the schema definition. Without it the
> >>parser (schema parser as well as JAXB) will try to validate the element
> >>against whatever type it finds for it in the schema.
> >>
> >>Pete
> >>
> >>Filip Rindler wrote:
> >>
> >>
> >>
> >>>Hi!
> >>>
> >>>I'm having another problem with the <xsd:extension> feature of XML
> >>>
> >>>
> >schema:
> >
> >
> >>>Here's an excerpt from my schema again:
> >>>
> >>><xsd:complexType name="Matrix">
> >>><xsd:attribute name="className" type="xsd:string" />
> >>></xsd:complexType>
> >>>
> >>><xsd:complexType name="Matrix2DGrid">
> >>><xsd:complexContent>
> >>> <xsd:extension base="Matrix">
> >>> <xsd:all>
> >>> <xsd:element name="size" type="Matrix2DGridDimension" />
> >>> <xsd:element name="neighborhoodRelation" type="xsd:int" />
> >>> <xsd:element name="cells" type="CellsList" />
> >>> </xsd:all>
> >>> </xsd:extension>
> >>></xsd:complexContent>
> >>></xsd:complexType>
> >>>
> >>>And here's an XML file that was generated (and validated) using
> >>>JAXB-generated classes:
> >>>
> >>><?xml version="1.0" encoding="UTF-8" standalone="yes"?>
> >>><ns1:mtxfile
> >>>xsi:schemaLocation="http://www.filip-rindler.de/cytorit/xml/mtxfile
> >>>http://www.filip-rindler.de/cytorit/xml/mtxfile.xsd"
> >>>
> >>>
>
>>xsi:noNamespaceSchemaLocation="http://www.filip-rindler.de/cytorit/xml/mtx
f
> >>
> >>
> >i
> >
> >
> >>>le http://www.filip-rindler.de/cytorit/xml/mtxfile.xsd"
> >>>xmlns:ns1="http://www.filip-rindler.de/cytorit/xml"
> >>>xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
> >>><ns1:minVersion>100</ns1:minVersion>
> >>><ns1:matrix className="de.filiprindler.cytorit.standard.Matrix2DGrid">
> >>><--- HERE
> >>><ns1:size>
> >>><ns1:origin>
> >>><ns1:x>1</ns1:x>
> >>><ns1:y>1</ns1:y>
> >>></ns1:origin>
> >>><ns1:width>10</ns1:width>
> >>><ns1:height>10</ns1:height>
> >>></ns1:size>
> >>><ns1:neighborhoodRelation>1</ns1:neighborhoodRelation>
> >>><ns1:cells></ns1:cells>
> >>></ns1:matrix>
> >>><ns1:parameters></ns1:parameters>
> >>></ns1:mtxfile>
> >>>
> >>>However, when reading the document I get a
> >>>[com.sun.msv.verifier.ValidityViolation: unexpected attribute
> >>>
> >>>
> >"className"]
> >
> >
> >>>exception!
> >>>How is this possible that I can successfully validate and save the file
> >>>
> >>>
> >but
> >
> >
> >>>when reding it, i get this exception?
> >>>I think it has something to do with the fact that the className
attribute
> >>>has been derived from the Matrix complexType to the Matrix2DGrid
subtype.
> >>>
> >>>Thanks!
> >>>
> >>>Filip Rindler
> >>>
> >>>
> >>>
> >>>
> >>>
> >
> >
> >
>