[英]Efficient merging of multiple, large xml files into one
我搜索了網絡,我上下搜索stackoverflow。 沒有解決方案。 雖然我在這里找到了解決方法如何在純xslt中執行此操作 。
但問題是產生的xml將是幾百MB大。 所以我必須用Java中的SAX來做這件事。 (請不要xslt解決方案,雖然我用xslt標記它;-))
讓我更詳細地解釋一下。 我有幾個應該解析的多個xml文件(最好是InputSteam)。 文件或InputStream看起來像
inputstream1
<root>
<doc>
<tag>test1</tag>
</doc>
<doc>
<tag>test2</tag>
</doc>
...
</root>
inputstream2
<root>
<doc>
<tag>test3</tag>
</doc>
<doc>
<tag>test4</tag>
</doc>
...
</root>
inputstream1 + inputstream2 + ... + inputstreamN = 結果xml 。 它看起來像
<root>
<doc>
<tag>test1</tag>
</doc>
<doc>
<tag>test2</tag>
</doc>
...
<doc>
<tag>test3</tag>
</doc>
<doc>
<tag>test4</tag>
</doc>
...
</root>
有人有解決方案或鏈接嗎? 這是通過實現自定義InputSource還是應該使用自定義ContentHandler? 或者這可能與joost / stx一起使用嗎?
如果我可以使用ContentHandler那么好的事情就是我可以應用一些小的轉換(我已經實現了這個)。 但問題是我不知道將多個文件或InputStream作為InputSource傳遞的方法:
XMLReader xmlReader = XMLReaderFactory.createXMLReader();
xmlReader.setContentHandler(customHandler);
xmlReader.parse(getInputSource()); // only one InputStream possible
或者我應該直接在ContentHandler中解析InputStreams?
我自己沒有這樣做,但我記得看到一篇IBM developerworks文章看起來很容易。
它現在有點舊了,但請嘗試http://www.ibm.com/developerworks/xml/library/x-tipstx5/index.html
這是StAX而不是SAX。 我不確定當前的JDK是否包含StAX。 如果沒有,你可以從http://stax.codehaus.org/獲得它
您可能想看看Saxon的付費版本。 它可以處理即時XSLT,而不需要內存中的完整DOM。
我終於通過以下片段進行了管理:
finalHandler = new StreamResult(new OutputStreamWriter(System.out));
// customHandler extends DefaultHandler
CustomTransformerHandler customHandler = new CustomTransformerHandler(
finalHandler);
customHandler.startDocumentExplicitly();
InputStream is = null;
while ((is = customHandler.createNextInputStream()) != null) {
// multiple inputStream parsing
XMLReader myReader = XMLReaderFactory.createXMLReader();
myReader.setContentHandler(customHandler);
myReader.parse(new InputSource(is));
}
customHandler.endDocumentExplicitly();
重要的是將startDocument和endDocument方法留空。 所有其他方法(字符,startElement,endElement)將被重定向到finalHandler。 如果讀取所有輸入流,則customHandler.createNextInputStream方法返回null。
合並文件的最有效方法是使用VTD-XML ,AFAIK提供的字節級剪切和粘貼功能。 你獲取兩個文件,將它們解析為VTDNav對象,然后實例化一個XMLModifier對象,從第二個文件中獲取片段,然后將它們插入到第一個文件中......這比SAX更有效..同時得到的XML將書寫方向寫入文件 - 無需將其存儲在內存中。 以下是不到20行的完整代碼......
import com.ximpleware.*;
import java.io.*;
public class merge {
// merge second.xml into first.xml assuming the same encoding
public static void main(String[] s) throws VTDException, IOException{
VTDGen vg = new VTDGen();
if (!vg.parseFile("d:\\xml\\first.xml", false))
return;
VTDNav vn1=vg.getNav();
if(!vg.parseFile("d:\\xml\\second.xml", false))
return;
VTDNav vn2 = vg.getNav();
XMLModifier xm = new XMLModifier(vn1);
long l = vn2.getContentFragment();
xm.insertBeforeTail(vn2, l);
xm.output("d:\\xml\\merged.xml");
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.