0

Ive written some code that creates an XML file from my System Properties in java. It works exactly how I want it to but I really (really) dont like how I ended up just using like 5 if statements to get it to work since I noticed none of the properties go beyond 4 delimited substrings anyways. Id much prefer using an iterator and some kind of hasNext() method to continue appending onto elements until the end of the string but I couldn't work anything out. I couldn't find a way to append the newest tag onto the last one in a loop/ add the value to the end of the elements.

This is what I currently have as a quick fix to get the program running.

Document doc = docBuilder.newDocument();
    Element rootElement = doc.createElement("JAVA");
    doc.appendChild(rootElement);

    Iterator it = hm.entrySet().iterator();
    while (it.hasNext()) 
    {
        Map.Entry entry = (Map.Entry) it.next();
        String keyString = (String)entry.getKey();
        String val = (String)entry.getValue();
        java.util.List<String> sa = Arrays.asList(keyString.split("\\."));

        Iterator ait = sa.iterator();

        Element tag = doc.createElement((String) ait.next());
        rootElement.appendChild(tag);

        Element tag2 = null;
        Element tag3 = null;
        Element tag4 = null;
        Element tag5 = null;

        while(ait.hasNext())
        {   
            if(ait.hasNext())
            {    
            tag2 = doc.createElement((String)ait.next());
            tag.appendChild(tag2);
            if(!ait.hasNext())
                tag2.appendChild(doc.createTextNode(val)); 

            }
            if(ait.hasNext())
            {    
            tag3=doc.createElement((String)ait.next());
            tag2.appendChild(tag3);
                if(!ait.hasNext())
                    tag3.appendChild(doc.createTextNode(val)); 
            }
            if(ait.hasNext())
            {    
            tag4=doc.createElement((String)ait.next());
            tag3.appendChild(tag4);
            if(!ait.hasNext())
                tag4.appendChild(doc.createTextNode(val)); 
            }
            if(ait.hasNext())
            {    
            tag5=doc.createElement((String)ait.next());
            tag5.appendChild(tag5);
            if(!ait.hasNext())
                tag5.appendChild(doc.createTextNode(val)); 
            }

        }

    }

    Transformer transformer = null;
    TransformerFactory transformerFactory = TransformerFactory.newInstance();
    try
    {
        DOMSource source = new DOMSource(doc);
        StreamResult result = new StreamResult(new File("XMLtester"));

        transformer = transformerFactory.newTransformer();
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
        transformer.transform(source, result);

    } catch (TransformerConfigurationException e)
    {
        e.printStackTrace();
    } catch (TransformerException e)
    {
        e.printStackTrace();
    }
    catch(NullPointerException e)
    {
        System.out.println("ERROR: " + e.toString());
    }
    System.out.println("File saved!");

If anyone has any ideas on how to make this a little more flexible or elegant so as to take in any number of delimited substrings id appreciate it.

1
  • Can you provide example input and output. Thanks. Commented May 9, 2014 at 5:29

1 Answer 1

2

I think this is what you want.

Element destination = rootElement;
Element tag = null;
while (ait.hasNext()) {
    tag = doc.createElement((String) ait.next());
    destination.appendChild(tag);
    destination = tag;
}
destination.appendChild(doc.createTextNode(val));

Example output:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<JAVA>
  <java>
    <runtime>
      <name>Java(TM) SE Runtime Environment</name>
    </runtime>
  </java>
  <sun>
    <boot>
      <library>
        <path>/Library/Java/JavaVirtualMachines/1.7.0.jdk/Contents/Home/jre/lib</path>
      </library>
    </boot>
  </sun>
  <java>
    <vm>
      <version>23.0-b19</version>
    </vm>
  </java>
  <user>
    <country>
      <format>GB</format>
    </country>
  </user>

Full working example:

import java.io.File;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class StackOverflow23556822 {

    public static void main(String[] args) throws ParserConfigurationException,
            TransformerException {
        DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance()
                .newDocumentBuilder();
        Document doc = docBuilder.newDocument();
        Element rootElement = doc.createElement("JAVA");
        doc.appendChild(rootElement);

        Iterator<?> it = System.getProperties().entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<?, ?> entry = (Map.Entry<?, ?>) it.next();
            String keyString = (String) entry.getKey();
            String val = (String) entry.getValue();
            List<String> sa = Arrays.asList(keyString.split("\\."));

            Iterator<?> ait = sa.iterator();

            Element destination = rootElement;
            Element tag = null;
            while (ait.hasNext()) {
                tag = doc.createElement((String) ait.next());
                destination.appendChild(tag);
                destination = tag;
            }
            destination.appendChild(doc.createTextNode(val));

        }

        Transformer transformer = null;
        TransformerFactory transformerFactory = TransformerFactory
                .newInstance();
        DOMSource source = new DOMSource(doc);
        StreamResult result = new StreamResult(new File("xml-test.xml"));

        transformer = transformerFactory.newTransformer();
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        transformer.setOutputProperty(
                "{http://xml.apache.org/xslt}indent-amount", "2");
        transformer.transform(source, result);

        System.out.println("File saved!");
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

This is perfect. Thanks so much. I tried a number of different approaches but this one never came to me. This is so so much better.
I find pencil and paper works wonders for complicated problems - figure out how you'd do it by-hand first.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.