Search code examples
javaxmljaxbpojo

Convert recursive XML to POJO and back


I've XML like this:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Trees>
    <Tree Id="1" Name="FirstTree" Type="Main Tree">
        <Description>Main Tree</Description>
        <Versions >
            <Version Id="20592" RootNodeId="117341" CreateDate="2018-01-17 17:01:38 Europe/Moscow" Status="EDIT" Label="TestTree">
                <Switch Id="117341" DisplayName="root structure"/>
                <Switch Id="117342" DisplayName="root structure">
                    <ScalarCase Id="40808"/>
                    <Switch Id="117343" DisplayName="root structure">
                        <ScalarCase Id="40809"/>
                         <Switch Id="117344" DisplayName="root structure">
                            <ScalarCase Id="40810"/>
                            <Leaf Id="117345"/> 
                            <Condition Id="117346">
                                <Leaf Id="117347"/>
                            </Condition>
                        </Switch>
                    </Switch>
                </Switch>
            </<Version>
        </Versions>
    </Tree>
</Trees>

How could my POJO look like the structure of this XML? It's unclear what the POJO should do to describe the Version object. I have the abstract class Nodeand created 3 inheritors: Switch, Leaf and Condition.

How can I make the recursive nesting of such objects to convert XML into an object and back?


Solution

  • Assuming that you have created the POJOs that mirror your xml, starting from:

    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlRootElement(name="Trees")
    public class Trees {
        private Tree Tree;
        // getters and setters
    }
    

    to Switch class (and the rest I will not write here):

    @XmlAccessorType(XmlAccessType.FIELD)
    public class Switch {
        private Condition Condition;
        private ScalarCase ScalarCase;
        private String Id;
        private String DisplayName;
        private Leaf Leaf;
        @XmlElement(name="Switch")
        private Switch aSwitch;
        // getters and setters
    }
    

    All your POJOs to have the proper annotations, etc.

    Then trying to read the xml into POJO, seems to work:

       public static void main(String[] args) {
    
            try {
                File file = new File("trees.xml");
                JAXBContext jaxbContext = JAXBContext.newInstance(Trees.class);
                Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
    
                Trees trees = (Trees) jaxbUnmarshaller.unmarshal(file);
                System.out.println(trees);
    
             } catch (JAXBException e) {
                e.printStackTrace();
            }
    
        }
    

    Edit: To reply to the comment in the answer section as well.

    When a class contains a field with itself as a type, it essentially creates a LinkedList so you can have any depth you want (within the memory limits).