user1110282
user1110282

Reputation: 21

Unmarshalling based on Concrete Instance

I am a new comer to JaxB World and I am facing one problem w.r.t. unmarshalling of the stored xml content into java class object. Problem description is as follows. Let me know if this is solvable I have my xsd file which contains following content(this is just a example) Student info

    <xs:complexType name="specialization" abstract="true">
    </xs:complexType>


    <xs:complexType name="Engineering">
        <xs:complexContent>
            <xs:extension base="specialization">
                <xs:sequence>
                    <xs:element name="percentage" type="xs:int" minOccurs="0"/>
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="Medical">
        <xs:complexContent>
            <xs:extension base="specialization">
                <xs:sequence>
                    <xs:element name="grade" type="xs:string" minOccurs="0"/>
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
</xs:complexType>

Now all the corresponding java classes are generated by compiling the xsd. Now lets assume in my application i will set the specialization attribute of Student info by constructing Engineering class instance. So after all the operation when i save the xml file that get saved will have the entry like below

<Student>
    <Name>Name1</Name>
    <Specialization>
        <percentage>78<percentage>
    </Specialization>
</Student>

Now when the above content goes for unmarshalling, unmarshalling fails saying unexpected element . I guess this is b'cos Specialization element is of type specialization it calls unmarshalling on itself rather than derived object which is stored.

I hope my explanation is clear. Is there any way that we can unmarshall based on derived class instanse type. The xsd and bindings.xjb file is completely in my control so i can add or modify any entries/info which conveys to unmarshalling rules to unmarshall on derived class.


Thanks for your Suggestion but the it still not working for me.

Here is what I tried

Option #1 - xsi:type
My xsd looks same as what is explained in the example but still the Xsi:type doesn't come in the resulted xml. Do i need to add any other setting while compiling? Which JaxB version should i use for this?

Option#2 - Substitution Groups
When i added the substitution entry part in my xsd, XSD compilation failed saying duplicate names "Engineering" and "Medical". I guess element name and type Name being same compilation cribs(All engineering, Medical,specialization being same both in type definition and element Name)

I can't modify the generated classes as we are using Model driven Architecture. Only thing that is in hand is xsd. Any modification to the xsd is allowed. Ideally First option should have worked. But can't figure out why it is not working. Let me know if you have some suggestion to narrow down the problem.

Upvotes: 2

Views: 403

Answers (1)

bdoughan
bdoughan

Reputation: 148977

There are different ways of representing Java inheritance in XML when using JAXB:

Option #1 - xsi:type

In this representation an attribute is used to indicate the subtype being used to populate this element.

<Student>
    <Name>Name1</Name>
    <Specialization xsi:type="Engineering">
        <percentage>78<percentage>
    </Specialization>
</Student>

For a detailed example see:

Option #2 - Substitution Groups

Here an element name is used to indicate the subtype. This corresponds to the schema concept of substitution groups and leverages JAXB's @XmlElementRef annotation:

<Student>
    <Name>Name1</Name>
    <Engineering>
        <percentage>78<percentage>
    </Engineering>
</Student>

For a detailed example see:

Upvotes: 1

Related Questions