Search code examples
javaxmljdom

create xml using jdom in java


I need to create xml using jdom with nested element with parent child relation. I have written code but xml not match with my requirement.In comment i have commented my required xml format. Please help me..

my code is

public static void main(String[] args) throws IOException {

    Map<String, String> map = new LinkedHashMap();
    map.put("webport", "/");
    map.put("webserverobsoluteurl", "https://");
    map.put("logger.folder", "/opt/apihandler/logs/wsapi");
    map.put("logger.port", "9001");
    map.put("logger.allowedlevel", "6");
    map.put("logpropsfile", "/opt/apihandler/WSAPIHandler/WEB-INF/log4j.properties");
    System.out.println(map);

    Element root = new Element("worldsmart");
    Document doc = new Document();
    Element pchild = null;

    for (Map.Entry<String, String> entry : map.entrySet()) {
        System.out.println(entry.getKey() + "=====================" + entry.getValue());

        if (entry.getKey().contains(".")) {

            int dotIndex = entry.getKey().indexOf(".");
            String parentTag = entry.getKey().substring(0, dotIndex);
            String childTag = entry.getKey().substring(dotIndex + 1, entry.getKey().length());
            pchild = new Element(parentTag);
            pchild.addContent(new Element(childTag).setText(entry.getValue()));
            root.addContent(pchild);

        } else {
            Element child = new Element(entry.getKey());
            child.addContent(entry.getValue());
            root.addContent(child);
        }
    }
    doc.setRootElement(root);
    XMLOutputter xmloutput = new XMLOutputter();
    xmloutput.setFormat(Format.getPrettyFormat());
    xmloutput.output(doc, new FileWriter("/root/Desktop/abc.xml"));
    System.out.println("file saved");
}

Required output:

<worldsmart>
    <webserverobsoluteurl>https://</webserverobsoluteurl>
    <webport>/</webport>
    <logger>
        <folder>/opt/apihandler/logs/wsapi</folder>
        <port>9001</port>
        <allowedlevel>6</allowedlevel>
    </logger>
    <logpropsfile> <![CDATA[ /opt/apihandler/WSAPIHandler/WEB-INF/log4j.properties ]]> </logpropsfile>
</worldsmart>

but I am getting XML file as

<worldsmart>
    <webport>/</webport>
    <webserverobsoluteurl>https://</webserverobsoluteurl>
    <logger>
        <folder>/opt/apihandler/logs/wsapi</folder>
    </logger>
    <logger>
        <port>9001</port>
    </logger>
    <logger>
        <allowedlevel>6</allowedlevel>
    </logger>
    <logpropsfile>/opt/apihandler/WSAPIHandler/WEB-INF/log4j.properties</logpropsfile>
</worldsmart>

Solution

  • @conscells, in a comment, has the right idea for what the problem is in your loops - you are creating a new logger element each time in the loop, instead of reusing the logger if it already exists (and creating it the first time in the loop).

    Your code:

       if (entry.getKey().contains(".")) {
    
            int dotIndex = entry.getKey().indexOf(".");
            String parentTag = entry.getKey().substring(0, dotIndex);
            String childTag = entry.getKey().substring(dotIndex + 1, entry.getKey().length());
            pchild = new Element(parentTag);
            pchild.addContent(new Element(childTag).setText(entry.getValue()));
            root.addContent(pchild);
    
        }
    

    should have a condition for checking for the pchild first:

       if (entry.getKey().contains(".")) {
    
            int dotIndex = entry.getKey().indexOf(".");
            String parentTag = entry.getKey().substring(0, dotIndex);
            String childTag = entry.getKey().substring(dotIndex + 1, entry.getKey().length());
    
            // locate the previously created `logger` element, if any.
            pchild = root.getChild(parentTag);
            if (pchild == null) {
    
                // need to add the child if it did not exist.
                pchild = new Element(parentTag);
                root.addContent(pchild);
            }
            pchild.addContent(new Element(childTag).setText(entry.getValue()));
    
        }