我需要从一个包含父元素及其子元素的地图生成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吗?
我想过递归,但我不知道从哪里开始。
有什么建议吗?
答案 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