I have an XML representing a hierarchical DOM where each element is an <element ...>
with zero or more children each. Each <element>
has a ton of attributes and I don't want to litter the Element
class with all those attributes, given it has a bunch of its own methods too.
The first draft of Element
class was as follows. This works flawlessly:
class Element {
@XmlAttribute private String name;
@XmlAttribute private String bounds;
// A whole bunch of other attributes
@XmlElement(name = "element") List<Element> children;
// A whole bunch of other methods
}
I tried to improve this by:
class Element {
@XmlPath(".") private Attributes attributes;
@XmlElement(name = "element") List<Element> children;
// A whole bunch of other methods
}
class Attributes {
@XmlAttribute private String name;
@XmlAttribute private String bounds;
// A whole bunch of other attributes
}
This seems to work fine, however, it actually messes up data upon closer inspection. If I input the following XML:
<element name="Hello" bounds="[0,0][1,1]">
<element name="World" bounds="[1,1][2,2]">
<element name="Testing" bounds="[2,2][3,3]">
<element name="One two three" bounds="[3,3][4,4]" />
</element>
</element>
</element>
The unmarshalled object has the following structure/properties:
+ [Element]
- name = "World"
- bounds = "[1,1][2,2]"
+ children[0]
- name = "Testing"
- bounds = "[2,2][3,3]"
+ children[0]
- name = "One two three"
- bounds = "[3,3][4,4]"
+ children[0]
- name = "One two three"
- bounds = "[3,3][4,4]"
- children = null
My assumption was that XPath(".")
would "lift" the attributes of the Attributes
class to the parent Element
class. But in fact it is lifting those attributes two levels upwards.
When I construct the Element
hierarchy manually, then try to marshall it, the resulting XML is just fine. It is just the unmarshalling that is producing the incorrect object.
Am I using XPath
incorrectly here? I have a working solution by including all attributes directly within the Element
class, but I just wanted to group those attributes into a separate class and marshall/unmarshall them to the container Element
class.
Thanks! Asim