views:

1026

answers:

2

I'm parsing an XML document that has nodes like the following:

<objects>
  <dog>
    <data1>...</data1>
    <data2>...</data2>
    <data3>...</data3>
  </dog>
  <cat>
    <data1>...</data1>
    <data2>...</data2>
    <data3>...</data3>
  </cat>
</objects>

The elements data1, data2, data3 are always consistent. Only the parent tag varies. In my object model I have a single Object which represents all of these cases. How can I get JAXB to handle this case without knowing in advance the name of the element?

@XMLAnyElement matches all the objects but doesn't create an object of the appropriate type; I get a list of Node objects instead of my object. My object currently looks something like:

public class MyObject {
    protected String otherData;

    @XmlAnyElement
    @XmlElementWrapper(name = "objects")
    protected List<MyChildObject> childObjects;
}

public class MyChildObject {
    protected String data1;
    protected String data2;
    protected String data3;
}

Any ideas how to handle this case short of changing the incoming XML format to use <object type="dog"> elements?

A: 

You can use inheritance:

@XmlRootElement(name = "dog")
public class MyDogObject extends MyChildObject {
    //nothing here
}

@XmlRootElement(name = "cat")
public class MyCatObject extends MyChildObject {
    //nothing here
}

This way it lets you deal with the same object type, MyChildObject, yet flexibly control the XML structure. Another benefit is that should you define specific dog/cat XML nodes in the future - they can be mapped on that corresponding subclass but not the other, as expected.

anikitin
This assumes that I know beforehand the universe of object names so I can create subclasses. For the time being I do, but it seems like a waste.
chetan
+1  A: 

If the name is truely dynamic, then I don't think JAXB will help you these. If you have a defined number of various element names then you could use inheritance like the other post suggested. If the number of elements and names is unknown I would recommend using something like this:

@XmlMixed
@XmlAnyElement
public List<Object> getObjects() {
    return objects;
}

This would bring the element is a just a DOM element. You could then use JAXB a second time to go from each of the elements into your custom type.

That would be if you had to use JAXB. You might find it easier to just use the SAX or DOM APIs directly for data like this. JAXB is really intended for well defined data that can be represented as a schema.

Chris Dail
Thanks, that make sense. We're going to go ahead and change the schema since we have that ability for the time being.
chetan