How to generate XML file from elements map?

user5997576

I need to generate an XML file from just having a map, which contains the parent element and his children.

Map looks like this:

Map<String, List<Element>> elementMap = new LinkedHashMap<String, List<Element>>();

root: el1 el2 el3 el4 // root is the parent and el1... are his children.
el1: el5 el6
el2: el7 el8

Expected XML Model:

<root>
  <el1>
    <el5></el5>
    <el6></el6>
  </el1>
  <el2>
    <el7></el7>
    <el8></el87>
  </el2>
  <el3></el3>
  <el4></el4>
</root>

Can you give me some tips, algorithms how I could generate that XML?
I thought about recursion, but I don't know where to start.

Any suggestions?

catch23

Your thoughts were good. You have to use iterating every one of your map keys and generate the list of elements based on values from this key. The result should be append to the general document.

You haven't posted your Element class. I will show some example based on Map<String, List<String>> elementMap.

Here is code snippet:

import com.epam.lab.model.exceptions.CreateDocumentConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.Text;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.util.Collections;
import java.util.List;
import java.util.Map;

public class XmlBuilder {

    private DocumentBuilder builder;

    private Document doc;

    /**
     * Constructs an item list builder.
     *
     * @throws CreateDocumentConfigurationException
     */
    public XmlBuilder() throws CreateDocumentConfigurationException {
        try {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            builder = factory.newDocumentBuilder();
        } catch (ParserConfigurationException e) {
            throw new CreateDocumentConfigurationException("exception create new document", e);
        }
    }

    /**
     * Builds a DOM document for an array list of items.
     *
     * @param elementMap map of items.
     * @return a DOM document describing the items.
     */
    public Document build(Map<String, List<String>> elementMap) {
        doc = builder.newDocument();
        doc.appendChild(createItems(elementMap));
        return doc;
    }

    /**
     * Builds a DOM element for an array list of items.
     *
     * @param elementMap the map of items
     * @return a DOM element describing the items
     */
    private Element createItems(Map<String, List<String>> elementMap) {
        Element e = null;
        for (Map.Entry<String, List<String>> anItem : elementMap.entrySet()) {
            e = doc.createElement(anItem.getKey());
            for (Node node : createItemsList(anItem.getValue())) {
                e.appendChild(node);
            }
        }
        return e;
    }

    private List<Node> createItemsList(List<String> items) {
        List<Node> result = new ArrayList<>();
        for (String item : items) {
            Element item1 = createItem(item);
            result.add(item1);
        }
        return result;
    }

    /**
     * Builds a DOM element for an item.
     *
     * @param anItem the item
     * @return a DOM element describing the item
     */
    private Element createItem(String anItem) {
        // if you need some text element to your element - just append it here.
        return doc.createElement(anItem);
    }

    /**
     * Builds the text content for document
     *
     * @param name element
     * @param text content
     * @return text element
     */
    private Element createTextElement(String name, String text) {
        Text t = doc.createTextNode(text);
        Element e = doc.createElement(name);
        e.appendChild(t);
        return e;
    }


    private String generateXmlContent(Map<String, List<String>> elementMap) {
        String content;

        Document doc = build(elementMap);
        DOMImplementation impl = doc.getImplementation();
        DOMImplementationLS implLS = (DOMImplementationLS) impl.getFeature("LS", "3.0");

        LSSerializer ser = implLS.createLSSerializer();
        ser.getDomConfig().setParameter("format-pretty-print", true);
        content = ser.writeToString(doc);

        return content;
    }

    public void writeToXmlFile(String xmlContent) {
        File theDir = new File("./output");
        if (!theDir.exists())
            theDir.mkdir();

        String fileName = "./output/" + this.getClass().getSimpleName() + "_"
                + Calendar.getInstance().getTimeInMillis() + ".xml";

        try (OutputStream stream = new FileOutputStream(new File(fileName))) {
            try (OutputStreamWriter out = new OutputStreamWriter(stream, StandardCharsets.UTF_16)) {
                out.write(xmlContent);
                out.write("\n");
            }
        } catch (IOException ex) {
            System.err.println("Cannot write to file!" + ex.getMessage());
        }
    }


    public static void main(String[] args) throws CreateDocumentConfigurationException {
        XmlBuilder xmlBuilder = new XmlBuilder();
        Map<String, List<String>> map = MapFactory.mapOf(MapFactory.entry("root", Arrays.asList("element1", "element2", "element3")));

        String xmlContent = xmlBuilder.generateXmlContent(map);
        xmlBuilder.writeToXmlFile(xmlContent);
    }
}

After generating XML document you have to write it to file.
But you have to prepare XML content before writing, something like:

private String generateXmlContent(Map<String, List<String>> elementMap) {
    String content;

    Document doc = build(elementMap);
    DOMImplementation impl = doc.getImplementation();
    DOMImplementationLS implLS = (DOMImplementationLS) impl.getFeature("LS", "3.0");

    LSSerializer ser = implLS.createLSSerializer();
    ser.getDomConfig().setParameter("format-pretty-print", true);
    content = ser.writeToString(doc);

    return content;
}

And finally writing to file can look like:

public void writeToXmlFile(String xmlContent) {
    File theDir = new File("./output");
    if (!theDir.exists())
        theDir.mkdir();

    String fileName = "./output/" + this.getClass().getSimpleName() + "_"
            + Calendar.getInstance().getTimeInMillis() + ".xml";

    try (OutputStream stream = new FileOutputStream(new File(fileName))) {
        try (OutputStreamWriter out = new OutputStreamWriter(stream, StandardCharsets.UTF_16)) {
            out.write(xmlContent);
            out.write("\n");
        }
    } catch (IOException ex) {
        System.err.println("Cannot write to file!", ex);
    }
}

Utility factory for creating Map, based on literals:

public class MapFactory {    
    // Creates a map from a list of entries
    @SafeVarargs
    public static <K, V> Map<K, V> mapOf(Map.Entry<K, V>... entries) {
        LinkedHashMap<K, V> map = new LinkedHashMap<>();
        for (Map.Entry<K, V> entry : entries) {
            map.put(entry.getKey(), entry.getValue());
        }
        return map;
    }
    // Creates a map entry
    public static <K, V> Map.Entry<K, V> entry(K key, V value) {
        return new AbstractMap.SimpleEntry<>(key, value);
    }
} 

After executing main() I have got following XML file XmlBuilder_1456910256665.xml:

<?xml version="1.0" encoding="UTF-16"?>
<root>
    <element1/>
    <element2/>
    <element3/>
</root>

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

How to filter elements from XML file

How to Generate an XML File from a set of XPath Expressions?

How to select all the names of elements and their quantities from a XML file?

How-To select elements from my XML-file in powershell

Powershell - how i read Elements from a XML File

How to retrieve all Elements from XML file using c#

how to generate the xml from oracle

Generate Javascript file for map from SQL database

How to add elements in an XML file?

How to generate a map file wth platformio

How to generate JSON with nested elements from MySql

Generate a heat map from CSV file using numpy and matplotlib - how to display negative numbers on axis

How to convert XML to JSON in node.js without having first two elements from xml file?

PHP copy multiple elements from an XML file to another XML file

Moving elements from one xml file to Another xml file

remove elements from XML file in java

read elements from an xml file using SAXReader

Prune some elements from large xml file

Removing elements from xml file with XLST

Replace elements with values from another xml file

How to map XML Wrapper with same elements and other elements

webSphere Liberty: How to generate an output file from an server.xml with only includes

Generate XML file with subnodes from xsd file using c#

How to generate XML from datatable in c#

How to generate dynamically XML from lists?

How generate the primary key from XML in Hibernate?

How to generate JAXB classes from just XML

How to generate XML for datatables that are empty from a dataset?

How to generate namespace prefixed xml elements using SimpleXMLElement in PHP