【问题标题】:generate xml by only knowing the element name and his parent通过只知道元素名称和他的父级来生成 xml
【发布时间】:2016-06-12 12:20:30
【问题描述】:

我想生成一个xml文件,如标题中所说。我需要的数据以XML_NAMEXML_PARENT_NAME 的形式存储在数据库表中,这是XML_NAME 的父级。

现在,你能给我一些想法,算法,如何只知道这两件事来生成我的xml文件吗?

提前致谢!

更新: XML 示例:

<root>
  <element1></element1>
  <element2></element2>
  <element3>
    <child>
      <text></text>
    </child>
  </element3>
</root>

数据库模型:

XML_NAME | XML_PARENT_NAME
root  
element1   root
element2   root
element3   root
child      element3
text       child 

我只有这个数据库条目,我需要从这些条目中构建一个 xml 文件,它看起来像上面的那个。

【问题讨论】:

  • 到目前为止你尝试过什么?您能否提供有关您需要的 XML 的更多信息?
  • 我现在正在处理它。 xml 看起来像一个普通的,没有什么特别的。它不需要有任何值,只需要标签。数据库表如下所示; XML_NAME | XML_PARENT_NAME 总计 |报告总收入 |总投资 |总...等等
  • 我不确定“正常”是什么意思。你想做吗:&lt;parent_name&gt;&lt;xml_name&gt;&lt;total&gt;123&lt;/total&gt;&lt;totalIncome&gt;987&lt;/totalIncome&gt;&lt;/xml_name&gt;&lt;parent_name&gt;
  • 好的。我已经编辑了我的帖子。我觉得现在有点清楚了。

标签: java xml


【解决方案1】:

这是一个易于实现的算法,假设您从数据库中检索到一个简单的结果集,其中包含您提到的两列。

  1. 首先遍历所有记录,并为每个 XML_NAME 名称构造一个 XML Node 对象(将 XML Node 对象放在一个列表中)。
  2. 使用字符串键(XML_NAME 名称)和 XML 节点对象作为值创建一个 HashMap。将每个 XML 节点作为一个条目添加到此映射中。
  3. 再次遍历所有记录(仅一次),对于每个 XML_NAME - XML_PARENT_NAME 对,在映射中查找两个 XML 节点对象。将前者的 XML 节点添加到后者的子节点列表中。
  4. 创建一个根 XML 节点。循环遍历 XML 节点列表并将每个没有父节点的节点添加到此根节点,作为根节点的子节点。
  5. 将根 XML 节点转换为字符串或对它进行任何操作。

【讨论】:

  • 我认为这可行。谢谢你。您在步骤 2 中说过。)使用字符串键创建地图。实际上是什么键?
  • XML_NAME 名称。编辑了答案以包含此内容。
【解决方案2】:

使用 XML 流编写器:

这是一个使用 FileWriter 将一系列事件写入磁盘的简单示例:

XMLOutputFactory factory      = XMLOutputFactory.newInstance();
try {
 XMLStreamWriter writer = factory.createXMLStreamWriter(
         new     FileWriter("data\\output2.xml"));

writer.writeStartDocument();
      writer.writeStartElement("document");
writer.writeStartElement("data");
writer.writeAttribute("name", "value");
writer.writeEndElement();
writer.writeEndElement();
 writer.writeEndDocument();

 writer.flush();
 writer.close();
} catch (XMLStreamException e) {
 e.printStackTrace();
} catch (IOException e) {
 e.printStackTrace();
}

执行此代码的结果是以下 XML 文件:

<?xml version='1.0' encoding='utf-8'?>
<document><data name="value"></data>    </document>

参考:http://tutorials.jenkov.com/java-xml/stax-xmlstreamwriter.html

如果您不需要值,只需使用 writeStartElement 和 writeEndElement

另外一个带有子元素的选项是:

Element root=new Element("CONFIGURATION");
Document doc=new Document();
Element child1=new Element("BROWSER");
child1.addContent("chrome");
Element child2=new Element("BASE");
child1.addContent("http:fut");
Element child3=new Element("EMPLOYEE");
child3.addContent(new     Element("EMP_NAME").addContent("Anhorn, Irene"));

root.addContent(child1);
root.addContent(child2);
root.addContent(child3);

doc.setRootElement(root);

XMLOutputter outter=new XMLOutputter();
outter.setFormat(Format.getPrettyFormat());
outter.output(doc, new FileWriter(new     File("myxml.xml")));

【讨论】:

  • 我认为问题不在于如何将 XML 实际写入文件——我认为 OP 知道这一点——而是如何使用他的数据库表中的结果集构建 XML 节点结构。
【解决方案3】:

您可以使用@mlkammer 建议的算法。

收集包含所有信息的最终地图后,您可以将其写入文件。

例如,您的地图显示为Map&lt;String, List&lt;String&gt;&gt; map

之后,您可以轻松地将其格式化并写入文件。

这里是代码 sn-p

import org.w3c.dom.*;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSSerializer;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.*;

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 version="1.0" encoding="UTF-16"?>
<root>
    <element1/>
    <element2/>
    <element3/>
</root>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-19
    • 2023-01-11
    • 1970-01-01
    相关资源
    最近更新 更多