简体   繁体   中英

Is it possible to use jaxb annotations to navigate objects after they are unmarshalled?

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 + '\'' + '}';
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM