Tuesday, December 20, 2011

JAXB - self-referential-objects-and-downcasting

You can solve the issue by marking the IdentifiableObject class with @XmlTransient: Nodes
package forum8257098;

import java.util.List;

import javax.xml.bind.annotation.*;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Nodes {

    @XmlElement(name="node")
    private List<Node> nodes;

}
Node
package forum8257098;

import javax.xml.bind.annotation.*;

@XmlRootElement
public class Node extends IdentifiableObject {

    @XmlElement
    private Node parent;

    @XmlElement
    private String aField;

}
IdentifiableObject
package forum8257098;

import javax.xml.bind.annotation.*;

@XmlTransient
public class IdentifiableObject {

    @XmlID
    @XmlAttribute
    private String id;

    @XmlAttribute
    private String name;

}
Demo
package forum8257098;

import java.io.File;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Nodes.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/forum8257098/input.xml");
        Nodes nodes = (Nodes) unmarshaller.unmarshal(xml);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(nodes, System.out);
    }

}
Input/Output
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<nodes>
    <node name="Node 1" id="49ad1cb6-f6fe-47f9-a544-4a1c6337c4a5">
        <aField>This is Node 1</aField>
    </node>
    <node name="Node 2" id="0a1d1895-49e1-4079-abc1-749c304cc5a2">
        <parent name="Node 1" id="49ad1cb6-f6fe-47f9-a544-4a1c6337c4a5"/>
        <aField>This is Node 2</aField>
    </node>
</nodes>
For More Information

No comments:

Post a Comment