簡體   English   中英

Java解析大型XML文檔

[英]Java parse large XML document

我正在嘗試解析並替換一個較大的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循環走得越久,花費的時間也就越長,平均10萬個節點需要花費2個小時以上的時間,而如果我只是手工分割出1k的較小塊,則將需要10秒鍾的時間。 解析此文檔的方式是否存在效率低下的問題?

- - 編輯 - -

根據對此的評論和答案,我切換到使用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,那么有一個更好的解決方案可以讓您兩全其美,並且已經過博客開源 從本質上講,這是SAX解析器之上非常輕巧的包裝,您可以在其中注冊您感興趣的XML元素,並且在獲取回調時,可以使用它們對應的部分DOM到XPath。

這樣,您可以保持恆定的復雜性(如上述博客中所述,擴展到超過1GB的XML文件),同時保持XPath的流暢性(將您感興趣的XML元素的DOM轉換)。

當為任務設計XSLT時,為什么要在Java中執行此操作?

45Mb是要保存在內存中的大文件,但仍然可行。 良好的XSLT處理器(例如Saxon)使用的樹模型比通用DOM(例如,因為它們是只讀的)效率要高得多(在存儲空間中均以搜索速度)。 XSLT具有更多的范圍來優化您的代碼。

我無法從您的代碼中對您的規范進行反向工程,但是在您的描述中我看不到任何本質上是非線性的。 我看不出在撒克遜地區需要花10多分鍾左右的任何原因。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM