输入文件包含数千个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>
(技术)用户应该提供类似<txn>
的输入标记名称。
我们希望提供更通用的解决方案。文件内容可能不同,用户可以提供类似“//transactions/txn
”的XPath表达式来选择单个事务。
我们在这里需要考虑的技术问题很少
我们可以在这种情况下使用StAX解析器吗?它必须将XPath表达式作为输入并选择/选择事务XML。
寻找建议。提前谢谢。
答案 0 :(得分:15)
如果性能是一个重要因素,和/或文档大小很大(这两者似乎都是这种情况),事件解析器(如SAX或StAX)与本机Java XPath实现之间的区别是后者在评估XPath表达式之前构建W3C DOM文档。 [值得注意的是,所有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事件过滤器(捕获您的<txn>
元素)。这将创建可以检查匹配用户值的小突发事件(元素,属性,文本)。在合适的匹配后,您可以从事件中提取必要的信息或管道有界事件,以便在您发现结果更容易导航时从中构建迷你DOM。但是如果标记很简单,那听起来似乎有些过分。
这可能是最简单,最快速的方法,可以避免构建DOM的内存开销。如果您将元素和属性的名称传递给过滤器(以便您的匹配算法是可配置的),您可以使它相对通用。
答案 1 :(得分:9)
Stax和xpath是非常不同的东西。 Stax允许您仅向前解析流式XML文档。 Xpath允许在两个方向上进行解析。 Stax是一个非常快速的流式XML解析器,但是,如果你想要xpath,java就有一个单独的库。
请看一下这个问题进行非常类似的讨论:Is there any XPath processor for SAX model?
答案 2 :(得分:2)
我们通过使用SAX解析器定期解析1GB +复杂XML文件,该解析器完全按照您的描述进行解析:它提取可以使用XPATH方便查询的部分DOM树。
我陷入困境here - 它使用的是SAX而不是StAX解析器,但可能值得一看。
答案 3 :(得分:1)
这绝对是XProc的一个用例,它具有流式和并行处理实现,如QuiXProc(http://code.google.com/p/quixproc)
在这种情况下,您必须使用
<p:for-each>
<p:iteration-source select="//transactions/txn"/>
<!-- you processing on a small file -->
</p:for-each>
您甚至可以用一行XProc
包装每个结果转换 <p:wrap-sequence wrapper="transactions"/>
希望这有帮助
答案 4 :(得分:0)
Streaming Transformations for XML (STX)可能就是您所需要的。
答案 5 :(得分:0)
您需要快速处理它还是需要快速查找数据?这些要求需要不同的方法。
为了快速读取整个数据,StAX就可以了。
如果您需要快速查找,而不是将其加载到某个数据库,例如Berkeley DB XML。
答案 6 :(得分:0)
处理大型XML文件&gt; 10GB的有趣解决方案。