JAXB / XJC parent-child-parent navigation

Viewed 6783

i would like to have bidirectional navigation methods in classes between child object and parent object. IDREF is not enough in my case because I don't want to specify le id of parent. to be clear, from an xsd like that:

<complexType name="A">
    <xs:sequence>
        <element name="b" type="B" minOccurs="0" maxOccurs="unbounded"></element>
    </xs:sequence>
    <attribute name="id" type="ID"></attribute>
</complexType>
<complexType name="B">
    <attribute name="id" type="ID"></attribute>
</complexType>

i would like classes looks like this:

class A {
    ...
    public List<B> getB() { ...}
    ...
   }
class B {
    ...
    public A getA() {
    ...
}

and my xml must looks like this:

<a id="a1">
    <b id="b1"/>
    <b id="b2"/>
    ...
</a>

After unmarshal, I would like to be able to navigate A to Bs AND from B to A (via b.getA()) !! It a very basic feature, but I don't find a simple way to achieve that ...

Any idea ??

Thanks in advance

5 Answers

To make swarmshine answer work with org.glassfish.jaxb:jaxb-runtime:jar:2.3.5, I made a few adjustments :

  • I had to annotate the BaseClass class and the parent attribute with @XmlTransient otherwise creating JAXBContext failed. It is because BaseClass is not defined in my XSD file
  • I did not need to extend Unmarshaller.Listener. I believe the runtime finds the afterUnmarshal method by itself, based on the name and the signature.
package mypackage;

import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlTransient;

@XmlTransient
public abstract class BaseClass {

    @XmlTransient
    private BaseClass parent;

    private void afterUnmarshal(Unmarshaller unmarshaller, Object parent){
        if (parent instanceof BaseClass){
            this.parent = (BaseClass) parent;
        }
    }

    public BaseClass getParent() {
        return this.parent;
    }
}
Related