Our Java application receives XML messages from a number of external systems and from these we want to create domain objects. We do not have schemas for these documents.
Currently we are are using XPaths to pull out strings from the XML and then calling setters on the new domain object. We use a home-baked XmlUtils class to do this.
foo.setBar(XmlUtils.number("/bar", document));
What alternative Java-based approaches are there, which do not require access to the document's schema?
Note: I'm the EclipseLink JAXB (MOXy) lead, and a member of the JAXB 2.X (JSR-222) expert group.
MOXy offers the @XmlPath
extension which enables you to do XPath based mapping:
Path Based Mapping
Match the bar
element under the foo
element:
@XmlPath("foo/bar/text()")
public int getBar() {
return bar;
}
Position Based Mapping
Match the second bar
element:
@XmlPath("bar[2]/text()")
public int getBar() {
return bar;
}
Predicate Based Mapping
Match the bar
element that has a type
attribute with value foo
:
@XmlPath("bar[@type='foo']/text()")
public int getBar() {
return bar;
}
Combined
All of the above concepts can be used together:
@XmlPath("foo[2]/bar[@type='foo']/text()")
public int getBar() {
return bar;
}
For More Information
I recommend using Apache Commons Digester for this. The usage pattern is something like this:
digester.addObjectCreate("parent", Parent.class);
digester.addObjectCreate("parent/child", Child.class);
digester.addCallMethod("parent/child", "setName", 1);
digester.addCallParam("parent/child/name", 0);
digester.addSetNext("parent/child", "addChild");
Also if you already have domain objects with structure similar to source xml, you can try to annotate it manually to unmarshal with JAXB.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With