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