users@jaxb.java.net

XML element polymorphism??

From: Filip Rindler <filip.rindler_at_gmx.de>
Date: Sat, 31 May 2003 16:33:02 +0200

Hi everybody!

My application is using JAXB for storing various types of 'matrices' in an
XML file. They are not mathematical matrices and the only thing important
here is the fact that all of them can have different properties. In my class
library i have created an abstract base class called "Matrix" and several
subclasses extending that matrix class (e.g. Matrix2DGrid).
I now want to use JAXB for storing arbitrary matrices in an XML file. For
that, each matrix can provide a MatrixXMLEncoder object that transforms this
matrix into a JAXB-element tree that then can be marshalled to the file.
The important parts of my schema look somewhat like this:

...

<xsd:complexType name="MTXFile">
 <xsd:all>
  <xsd:element name="minVersion" type="xsd:int" />
  <xsd:element name="matrix" type="Matrix" />
 </xsd:all>
</xsd:complexType>

<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>

.... [more matrix types]

This XML encoder mentioned above always polymorphically returns a XMLBMatrix
element (that's the XMLB class corresponding to the Matrix element type),
i.e. the runtime type is a subclass of XMLBMatrix. This works, because JAXB
is as smart as to recognize the <xsd:extension base="Matrix"> tag and let
XMLBMatrix2DGrid (XMLB class corresponding to the Matrix2DGrid element type)
extend the XMLBMatrix class. In the schema above it might become clear, that
the 'Matrix' element type could be called 'abstract', because it will never
actually occur in the document, only its derived elements (such as
Matrix2DGrid) will occur.

OK, now after this long tale, here's my problem: While it seems to work to
just assign a XMLBMatrix2DGrid object to the 'mtxfile' root element using
its generated setMatrix() method, i get a validation error. So is there a
way of somewhat using polymorphism in one or another way? For me it would be
best if all these different Matrix subclasses could be simply stored into
the 'matrix' sub-element of 'mtxfile' (of course only one). I dont really
want something like a <xsd:choice> with different matrix tags available for
different matrix classes, because I want the user to have the possibility to
add new matrix types later. I should add that there is no problem for my
application identifying the type of the matrix when unmarshalling, because
the matrix class file name is saved in the 'className' attribute of the
'Matrix' type. When unmarshalling my matrix, it is easy to resolve that name
into a class that then can be asked to provide an appropriate XML decoder.

I'm not stubborn on the stuff I've written so far and if there's another way
of accomplishing my goal, I can change everything, just to have that said
;-)

Thanks in advance!

Filip Rindler