4

我搜索了网络,并上下搜索了stackoverflow。没有解决方案。虽然我在这里找到了如何在纯 xslt 中执行此操作的解决方案。

但问题是生成的 xml 将有数百 MB 大。所以我必须用 Java 中的 SAX 来做这件事。(请不要使用 xslt 解决方案,尽管我用 xslt 对其进行了标记;-))

让我更详细地解释一下。我有几个应该解析的多个 xml 文件(最好是 InputSteam)。文件或 InputStream 的样子

输入流1

<root>
  <doc>
    <tag>test1</tag>
  </doc>
  <doc>
    <tag>test2</tag>
  </doc>
  ...
</root>

输入流2

<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?

4

4 回答 4

2

我自己还没有这样做,但我记得看过一篇 IBM developerworks 文章,看起来它使这变得非常容易。

现在有点老了,但试试http://www.ibm.com/developerworks/xml/library/x-tipstx5/index.html

这是 StAX 而不是 SAX。我不确定当前的 JDK 是否包括 StAX。如果没有,您可能可以从http://stax.codehaus.org/获得它

于 2010-02-16T20:42:55.477 回答
1

您可能想看看付费版的撒克逊语。它可以处理动态 XSLT,而不需要内存中的完整 DOM。

于 2010-02-16T20:08:46.973 回答
0

我终于通过以下代码片段进行了管理:

  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。

于 2010-02-16T23:31:20.377 回答
0

合并文件的最有效方法是使用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");   
    }
}
于 2010-02-18T09:11:24.767 回答