I have a fairly complex XML schema and I use hyperjaxb3 to generate pojo's with annotations for. There are times when I have the parent object and would like to check the value of a child object that may be 8 or 9 children deep. Is there anyway to use jaxb, or another tool, to get a list of child objects of a specific class based on jaxb annotations?
I could write a recursive function to search all children for an instance of a class but that would be less than ideal. Any advise would be appreciated, thanks.
You don't have to write the code to walk the object tree yourself — there are a few out there already (jdereg's java-util for example), and the JAXBIntrospector
will find objects annotated with XmlRootElement
for you. There would be a little more work required if you're looking for other annotations, but not much.
For example:
public static void main(String[] args) throws JAXBException {
JAXBContext jc = JAXBContext.newInstance(Foo.class);
JAXBIntrospector is = jc.createJAXBIntrospector();
// Found objects
List<Foo.Bar> bars = new ArrayList<>();
// Object name to look for
QName barName = new QName("", "bar");
// Unmarshalled root object to introspect
Foo target = new Foo(new Foo.Bar());
// Walk the object graph looking for "bar" elements
Traverser.traverse(target, o -> {
if (barName.equals(is.getElementName(o))) {
bars.add((Foo.Bar) JAXBIntrospector.getValue(o));
}
});
System.out.println(bars);
}
//
// Some test objects
//
@XmlRootElement(name = "foo")
public class Foo {
private Bar bar;
public Foo() { }
public Foo(Bar bar) {
this.bar = bar;
}
@XmlElement(name="bar")
public Bar getBar() {
return bar;
}
public void setBar(Bar bar) {
this.bar = bar;
}
@XmlRootElement(name="bar")
public static class Bar {
String name = "kate";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Bar{name='" + name + '\'' + '}';
}
}
}