SAX模型是否有任何XPath处理器?
我正在寻找一个XPath评估器,它不重build整个DOM文档来查找文档的节点:实际上,对象是用SAX模型pipe理大量的XML数据(理想情况下超过2Gb)有利于内存pipe理,并可以search节点。
谢谢大家的支持!
对于所有那些说不可能的人:我最近在问了这个问题之后,find了一个名为“saxpath”的项目( http://www.saxpath.org/ ),但是我找不到任何的实施项目。
我目前的列表(从networkingsearch结果和其他答案编译)是:
- http://code.google.com/p/xpath4sax/
- http://spex.sourceforge.net/
- https://github.com/santhosh-tekuri/jlibs/wiki/XMLDog (还包含一个性能图表)
- http://www.cs.umd.edu/projects/xsq/ (单行项目,10年以来死亡,GPL)
- MIT许可方法http://softwareengineeringcorner.blogspot.com/2012/01/conveniently-processing-large-xml-files.html
- 其他parsing器/支持快速XPath的内存模型:
下一步是使用XMLDog的例子,并比较所有这些方法的性能。 然后,testing用例应该扩展到支持的XPathexpression式。
我们通过使用SAXparsing器定期parsing1GB +复杂的XML文件,该parsing器可以提取部分DOM树,可以使用XPath方便地查询。 我在这里博客: http : //softwareengineeringcorner.blogspot.com/2012/01/conveniently-processing-large-xml-files.html – 源代码在github上可用 – MIT许可证。
XPath可以和SAX一起工作,而且大多数XSLT处理器(特别是Saxon和Apache Xalan)都支持在SAXstream的XSLT中执行XPathexpression式,而不需要构build整个dom。
他们设法做到这一点,非常粗略,如下所示:
- 检查他们需要匹配的XPathexpression式
- 接收SAX事件并testing该XPathexpression式是否需要或将需要该节点。
- 如果对XPathexpression式没有用处,则忽略SAX事件。
- 缓冲它,如果需要的话
他们如何缓冲它也是非常有趣的,因为一些简单的创buildDOM碎片,其他人使用非常优化的表来快速查找和减less内存消耗。
他们设法优化多less主要取决于他们find的XPath查询的种类。 正如已经发布的Saxon文档清楚地解释的那样,向上移动然后“横向”(兄弟姐妹)移动文档的查询显然需要整个文档在那里,但是大多数只需要将几个节点保存到RAM在任何时刻。
我非常肯定这一点,因为当我每天都在使用Cocoon制作Web应用程序时,每当我们在XSLT中使用“// something”expression式时,都会遇到XSLT内存占用问题,通常我们不得不重写XPathexpression式以实现更好的SAX优化。
SAX是仅向前的,而XPath查询可以在任何方向上浏览文档(考虑parent::
, ancestor::
, preceding::
和preceding-sibling::
axis)。 我不明白这是如何可能的一般。 最好的近似是某种延迟加载的DOM,但根据您的查询,这可能会或可能不会给您带来任何好处 – 总会有最差情况的查询,例如//*[. != preceding::*]
//*[. != preceding::*]
。
对不起,这里稍微迟一点的答案 – 似乎这对于XPath的一个子集是可能的 – 总的来说这很困难,因为XPath可以从“当前”点向前和向后匹配。 我知道有两个项目使用状态机在一定程度上解决了这个问题: http : //spex.sourceforge.net&http : //www.cs.umd.edu/projects/xsq 。 我没有详细看过他们,但他们似乎使用了类似的方法。
我会为了一个叫做AXS的新项目而投入一个插件。 它位于https://code.google.com/p/annotation-xpath-sax/ ,其思想是您使用(仅向前轴)XPath语句注释方法,并在SAXparsing器处于节点时被调用匹配它。 所以用一个文件
<doc> <nodes> <node name="a">text of node 1</node> <node name="b">text of node 2</node> <node otherattr="I have attributes!">text of node 3</node> </nodes> </doc>
你可以做类似的事情
@XPath("/nodes/node") void onNode(String nodeText) { // will be called with "text of node [123]" }
要么
@XPathStart("//node[@name='']") void onNode3(Attrs node3Attrs) { ... }
要么
@XPathEnd("/nodes/node[2]") void iDontCareAboutNode3() throws SAXExpression { throw new StopParsingExpression(); }
当然,图书馆是如此的新,我甚至还没有发布它,但它是麻省理工学院许可的,所以随时试一试,看看它是否符合你的需要。 (我写它做HTML屏幕刮擦足够低的内存要求,我可以在旧的Android设备上运行…)如果你发现错误,请让我知道在Googlecode网站上提交他们!
对不起,迟来的答案,但我没有实现SAXparsing器的简单的XPathexpression式path。 它只支持标签,具有可选值的属性,以及由于SAX的前向性而产生的索引。 当Handler实现ExpressionFilter时,我做了一个委托处理程序来评估给定的expression式。 虽然这些类embedded到项目中,但不应该难以提取。
更多信息
示例 – 使用HandlerHtml
前缀查看类
有基于SAX / StAX的XPath实现,但是它们只支持XPathexpression式/轴的一个小子集,很大程度上是由于SAX / StAX的仅向前性质。我知道的最好的select是扩展的VTD-XML ,它支持完整的xpath,通过mem-map加载部分文档,最大文档大小为256GB,但是您需要64位JVM才能充分利用它
嗯,我不知道我是否真的了解你。 据我所知,SAX模型是面向事件的。 这意味着,如果在parsing过程中遇到某个节点,则会执行某些操作。 是的,这对内存来说更好,但是我不明白你想如何获得XPath。 由于SAX不构build模型,我不认为这是可能的。
你可以做的是将一个XSL转换器挂接到一个SAXinput源。 你的处理将是连续的,XSL预处理器会尝试捕捉input,以便将它转换为你指定的结果。 你可以使用这个从stream中拉出path的值。 如果您想要一次生成一堆不同的XPATH结果,这将特别方便。
您将(通常)得到一个XML文档,但是您可以从StreamResult
获得预期的输出,而不会太麻烦。
看看Saxon-SA XSLT处理器的stream模式。
http://www.saxonica.com/documentation/sourcedocs/serial.html
“确定pathexpression式是否可以stream式处理的规则是:
- 要进行stream式处理的expression式首先调用document()或doc()函数。
-
doc()或文档上的调用引入的pathexpression式必须符合XPath的子集,定义如下:
-
如果任何XPathexpression式符合出现在XML模式中的标识约束中的pathexpression式的规则,则该expression式是可接受的。 这些规则不允许谓词; 第一步(但只有第一步)可以用“//”来引入; 最后一步可以select使用属性轴; 所有其他步骤必须是简单的轴步骤使用子轴。
- 另外,Saxon允许expression式包含一个联合,例如doc()/(* / ABC | / XYZ)。 联盟也可以用缩写forms表示,例如上面可以写成doc()/ /(ABC | XYZ)。
-
该expression式必须仅select元素,或仅select属性,或者select元素和属性的混合。
-
简单的filter(一个或多个)也被支持。 每个filter可以应用到最后一步或整个expression式,并且只能从上下文节点(自我,孩子,属性,后代,后代或自我或名称空间轴)向下select。 它不能是位置的(也就是说,它不能引用position()或last(),也不能是numeric:实际上,它必须是Saxon在编译时可以确定它不会是数字的)。 filter不能应用于工会或工会的分支。 任何违反这些条件的情况都会导致在没有stream式优化的情况下评估expression式。
-
这些规则适用于其他优化重写已应用到expression式之后。 例如,一些FLWORexpression式可以被重写为满足这些规则的pathexpression式。
-
只有通过使用saxon:stream()扩展函数或者在XSLT xsl:copy-of指令或者XQuery pragma saxon:stream中使用saxon:read-once属性,才能显式请求优化。 只有使用Saxon-SA处理样式表或查询时才可用。“
注意:这个工具最有可能在商业版本中可用。 我之前广泛使用过撒克逊,这是一件很好的工作。
我不认为xpath可以与SAX协同工作,但是您可以看看StAX,这是一个扩展的用于Java的stream式XML API。
标准的javax xpath API在技术上已经可以在stream中使用; javax.xml.xpath.XPathExpression
可以用一个InputSource
来评估,而InputSource
又可以用Reader
来构build。 我不认为它构build了一个DOM下的封面。
你有没有尝试过QuiXPath https://code.google.com/p/quixpath/ ?
- 将Double值格式化为2的最佳方法小数位
- 为什么JAXB需要一个无参数构造器来进行编组?
- 通过热插拔机制在运行时更改方法
- 为什么使用ReentrantLock如果可以使用synchronized(this)?
- 为什么findFirst()如果find的第一个元素为null,会抛出NullPointerExceptionexception?
- RabbitMQ AMQP.BasicProperties.Builder值
- 如何防止在Spring 3.0.5中解释逗号的参数绑定?
- 在java中布尔值的默认值
- org.hibernate.MappingException:无法确定types:java.util.Set