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

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

文件的示例内容

   product 1 29.99    product 2 59.59   

(技术)用户应该给出输入标签名称,如

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

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

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

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

寻找建议。 提前致谢。

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

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

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

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

  Document document = getParser().parse( source ); 

在此之后,您的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实现(根据我的经验,这是非常快的),我建议创建一个首先匹配元素类型名称的XML事件filter(以捕获你的元素)。 这将创建可以检查匹配用户值的小突发事件(元素,属性,文本)。 在合适的匹配时,如果您发现结果更容易导航,您可以从事件中提取必要的信息或管道有界事件以构建一个迷你DOM。 但是如果标记很简单,那听起来似乎有些过分。

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

这绝对是XProc的一个用例,它具有流式和并行处理实现,如QuiXProc( http://code.google.com/p/quixproc

在这种情况下,你将不得不使用

      

您甚至可以使用一行XProc来包装每个结果转换

   

希望这可以帮助

我们通过使用SAX解析器定期解析1GB +复杂的XML文件,它完全按照您的描述进行解析:它提取可以使用XPATH方便查询的部分DOM树。

我在这里陷入困境 – 它使用的是SAX而不是StAX解析器,但值得一看。

XML(STX)的流式转换可能就是您所需要的。

您需要快速处理它还是需要快速查找数据? 这些要求需要不同的方法。

为了快速读取整个数据,StAX就可以了。

如果您需要快速查找而不是将其加载到某个数据库,Berkeley DB XML例如

处理大型XML文件> 10GB的有趣解决方案。

  1. 使用ANTLR为感兴趣的部分创建字节偏移。 与基于DOM的方法相比,这将节省一些内存。
  2. 使用Jaxb从字节位置读取部件

在此SO答案中以维基百科转储(17GB)为例查找详细信息https://stackoverflow.com/a/43367629/1485527