如何从元素映射生成XML文件?

时间:2016-03-02 08:04:17

标签: java xml recursion

我需要从一个包含父元素及其子元素的地图生成XML文件。

地图如下所示:

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

预期 XML模型

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

您能给我一些提示,算法如何生成该XML吗?
我想过递归,但我不知道从哪里开始。

有什么建议吗?

2 个答案:

答案 0 :(得分:0)

你的想法很好。 您必须使用迭代每个地图键并根据此键的值生成元素列表。结果应该附在一般文件上。

您尚未发布Element课程。我将根据Map<String, List<String>> elementMap显示一些示例。

以下是代码段:

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);
    }
}

生成 XML文档 后,您必须将其写入文件。
但在撰写之前,您必须 准备XML内容 ,例如:

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);
    }
}

基于文字创建Map的实用工厂:

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);
    }
} 

执行main()后,我得到了以下XML文件XmlBuilder_1456910256665.xml

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

答案 1 :(得分:-1)

您可以使用以下功能将Map转换为XML字符串。

public static String maptoXML(Object hashMap) {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    XMLEncoder xmlEncoder = new XMLEncoder(bos);
    xmlEncoder.writeObject(hashMap);
    xmlEncoder.close();
    return bos.toString();
}

价:http://pritomkumar.blogspot.in/2014/05/convert-map-hashmap-or-listarraylist-to.html?m=1