[英]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.