Java解析大型XML文档

标签 java xml

我正在尝试解析和替换大型 xml 文件中的值,每个文件大约 45MB。我这样做的方式是:

private void replaceData(File xmlFile, File out)
{
    DocumentBuilderFactory df = DocumentBuilderFactory.newInstance();
    DocumentBuilder db = df.newDocumentBuilder();
    Document xmlDoc = db.parse(xmlFile);
    xmlDoc.getDocumentElement().normalize();

    Node allData = xmlDoc.getElementsByTagName("Data").item(0);
    Element ctrlData = getSubElement(allData, "ctrlData");
    NodeList subData = ctrlData.getElementsByTagName("SubData");

    int len = subData.getLength();

    for (int logIndex = 0; logIndex < len; logIndex++) {

        Node log = subData.item(logIndex);
        Element info = getSubElement(log, "info");
        Element value = getSubElement(info, "dailyInfo");
        Node valueNode = value.getElementsByTagName("value").item(0);
        valueNode.setTextContent("blah");               
    }

    TransformerFactory tf = TransformerFactory.newInstance();
    Transformer t = tf.newTransformer();
    DOMSource s = new DOMSource(xmlDoc);
    StreamResult r = new StreamResult(out);
    t.transform(s, r);

    } catch (TransformerException | ParserConfigurationException | SAXException | IOException e) {
         throw e;
    }
}

private static Element getSubElement(Node node, String elementName)
{
        return (Element)((Element)node).getElementsByTagName(elementName).item(0);
}

我注意到随着 for 循环的深入,它花费的时间越长,平均 100k 个节点需要 2 多个小时,而如果我只是手动分解 1k 个较小的 block ,则需要 ~10s .此文档的解析方式是否存在效率低下的问题?

----编辑----

根据对此的评论和回答,我转而使用 Sax 和 XmlStreamWriter。此处引用/示例:http://www.mkyong.com/java/how-to-read-xml-file-in-java-sax-parser/

在转为使用 SAX 后,replaceData 函数的内存使用不会扩展到 XML 文件的大小,并且 XML 文件处理时间平均约为 18 秒。

最佳答案

正如人们在评论中提到的,将整个 DOM 加载到内存中,尤其是对于大型 XML,效率非常低,因此更好的方法是使用 SAX 解析器不断的内存。缺点是您无法获得将整个 DOM 存储在内存中的流畅 API,并且如果您想在嵌套节点中执行复杂的回调逻辑,可见性非常有限。

如果您感兴趣的只是解析特定节点和节点系列而不是解析整个 XML,那么有一个更好的解决方案可以让您兼顾两者世界和一直blogged aboutopen-sourced .它基本上是 SAX 解析器之上的一个非常轻的包装器,您可以在其中注册您感兴趣的 XML 元素,并且当您获得回调时,您可以随意使用它们对应的部分 DOM 到 XPath。

通过这种方式,您可以在恒定时间保持复杂性(如上述博客中所述,扩展到超过 1GB 的 XML 文件),同时保持 XPath 对您感兴趣的 XML 元素的 DOM 的流畅性。

关于Java解析大型XML文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23276471/

相关文章:

java - jdk1.6下可用 "tools.jar"的源代码

java - 加载 ScriptC 脚本失败/无法加载库 - Renderscript Android

java - 为什么我的 R 文件丢失?在一个全新的项目上。

java - APK 文件的元数据?

java - 如何在远程weblogic服务器上热部署Web应用程序?

android - "No XML content. Please add a root view or layout to your document"

javascript - xsd 类型 javascript 的限制

javascript - 解析 Youtube 视频源 XML

java - 访问实现接口(interface)的类的独特方法

xml - XML 属性可以是空字符串吗?