使用StAX和XPath读取大量XML文件

Siv*_*lam 10 java xml xpath stax

输入文件包含数千个XML格式的事务,大小约为10GB.要求是根据用户输入选择每个事务XML并将其发送到处理系统.

文件的示例内容

<transactions>
    <txn id="1">
      <name> product 1</name>
      <price>29.99</price>
    </txn>

    <txn id="2">
      <name> product 2</name>
      <price>59.59</price>
    </txn>
</transactions>
Run Code Online (Sandbox Code Playgroud)

(技术)用户应该给出输入标签名称<txn>.

我们希望提供更通用的解决方案.文件内容可能不同,用户可以提供类似" //transactions/txn" 的XPath表达式来选择单个事务.

我们在这里需要考虑的技术问题很少

  • 该文件可以位于共享位置或FTP中
  • 由于文件很大,我们无法在JVM中加载整个文件

我们可以在这种情况下使用StAX解析器吗?它必须将XPath表达式作为输入和选择/选择事务XML.

寻找建议.提前致谢.

Ich*_*ato 15

如果性能是一个重要因素,和/或文档大小很大(这两者似乎都是这种情况),事件解析器(如SAX或StAX)与本机Java XPath实现之间的区别在于后者构建在评估XPath表达式之前的W3C DOM Document.[值得注意的是,所有Java文档对象模型实现(如DOM或Axiom)都使用事件处理器(如SAX或StAX)来构建内存中表示,因此如果您只使用事件处理器,那么节省内存和构建DOM所需的时间.]

正如我所提到的,JDK中的XPath实现在W3C DOM文档上运行.您可以在Java JDK源代码实现中看到这一点,在com.sun.org.apache.xpath.internal.jaxp.XPathImpl调用evaluate()方法之前,解析器必须首先解析源:

  Document document = getParser().parse( source );
Run Code Online (Sandbox Code Playgroud)

在此之后,你的10GB XML将在内存中表示(加上任何开销) - 可能不是你想要的.虽然你可能想要一个更"通用"的解决方案,但你的示例XPath和你的XML标记看起来都相对简单,所以似乎没有一个非常强大的XPath理由(除了编程优雅).对于XProc建议也是如此:这也将构建一个DOM.如果你真的需要一个DOM,你可以使用Axiom而不是W3C DOM.Axiom有一个更友好的API,并通过StAX构建其DOM,所以它很快,并使用Jaxen进行XPath实现.Jaxen需要某种 DOM(W3C DOM,DOM4J或JDOM).这对于所有XPath实现都是如此,所以如果你真的不需要XPath坚持使用事件,那么建议使用解析器.

SAX是旧的流API,StAX更新,速度更快.使用本机JDK StAX实现(javax.xml.stream)或Woodstox StAX实现(根据我的经验,这是非常快的),我建议创建一个首先匹配元素类型名称(捕获<txn>元素)的XML事件过滤器.这将创建可以检查匹配用户值的小突发事件(元素,属性,文本).在合适的匹配后,您可以从事件中提取必要的信息或管道有界事件,以便在您发现结果更容易导航时从中构建迷你DOM.但是如果标记很简单,那听起来似乎有些过分.

这可能是最简单,最快的方法,并避免构建DOM的内存开销.如果您将元素和属性的名称传递给过滤器(以便您的匹配算法是可配置的),您可以使它相对通用.

  • 直到您发表评论,不,我才没有。我已经下载了发行版,很乐意尝试一下。它的性能是否符合我的考虑,我会考虑在生产环境中使用它,但是我看到的一个问题促使我问(因为您是它的作者)是否愿意在LGPL或Apache下发布vtd-xml?执照?我们根本无法在我们的环境中使用GPL。无论如何,感谢您的提示。 (2认同)

Jon*_*on7 9

Stax和xpath是非常不同的东西.Stax允许您仅向前解析流式XML文档.Xpath允许在两个方向上进行解析.Stax是一个非常快速的流式XML解析器,但是,如果你想要xpath,java有一个单独的库.

看一下这个问题进行非常类似的讨论:是否有适用于SAX模型的XPath处理器?

  • 如果您打算投票,请发表评论.那样每个人都学会了! (2认同)