是否有适用于SAX型号的XPath处理器?

时间:2009-12-07 22:05:07

标签: java xml xpath sax

我正在寻找一个XPath评估器,它不会重建整个DOM文档来查找文档的节点:实际上,该对象是使用SAX模型管理大量XML数据(理想情况下超过2Gb),这对内存管理非常有用,并且可以搜索节点。

谢谢大家的支持!

对于所有那些说不可能的人:我最近在问到这个问题后,发现了一个名为“saxpath”(http://www.saxpath.org/)的项目,但我找不到任何实施项目。

14 个答案:

答案 0 :(得分:15)

我当前的列表(根据网络搜索结果和其他答案编译)是:

下一步是使用XMLDog的示例并比较所有这些方法的性能。然后,测试用例应扩展到支持的XPath表达式。

答案 1 :(得分:11)

我们通过使用SAX解析器定期解析1GB +复杂XML文件,该解析器提取可以使用XPath方便查询的部分DOM树。我在这里写了博客:http://softwareengineeringcorner.blogspot.com/2012/01/conveniently-processing-large-xml-files.html - 来源可以在github - 麻省理工学院许可证上找到。

答案 2 :(得分:9)

XPath可以与SAX一起使用,大多数XSLT处理器(特别是Saxon和Apache Xalan)都支持在SAX流上的XSLT中执行XPath表达式,而不需要构建整个dom。

他们设法非常粗略地执行此操作,如下所示:

  1. 检查他们需要匹配的XPath表达式
  2. 接收SAX事件并测试是否需要该节点或其中一个XPath表达式需要该节点。
  3. 如果对XPath表达式没用,请忽略SAX事件。
  4. 如果需要则缓冲
  5. 他们如何缓冲它也很有趣,因为有些人只是在这里和那里简单地创建DOM片段,其他人使用非常优化的表来快速查找和减少内存消耗。

    他们设法优化的程度在很大程度上取决于他们找到的XPath查询的类型。正如已经发布的Saxon文档清楚地解释的那样,向上移动然后“横向”遍历(兄弟姐妹)文档的查询显然需要整个文档存在,但是大多数文档只需要保留几个节点RAM随时都有。

    我很确定这一点,因为当我每天仍在使用Cocoon制作webapp时,每次我们在XSLT中使用“// something”表达式时,我们都遇到了XSLT内存占用问题,而且我们经常不得不重写XPath表达式以允许更好的SAX优化。

答案 3 :(得分:6)

SAX是仅向前的,而XPath查询可以向任何方向导航文档(考虑parent::ancestor::preceding::preceding-sibling::轴)。我不知道一般来说这是怎么可能的。最好的近似值是某种延迟加载DOM,但根据您的查询,这可能会或可能不会给您带来任何好处 - 总是存在最坏情况的查询,例如//*[. != preceding::*]

答案 4 :(得分:4)

对不起,这里的回答稍晚 - 似乎这对XPath的一个子集来说是可能的 - 一般而言,由于XPath可以从“当前”点向前和向后匹配这一事实非常困难。我知道有两个项目在某种程度上使用状态机来解决它:http://spex.sourceforge.net& http://www.cs.umd.edu/projects/xsq。我没有详细看过它们,但它们似乎采用了类似的方法。

答案 5 :(得分:3)

我将为我的一个名为AXS的新项目插上插头。它位于https://code.google.com/p/annotation-xpath-sax/,并且您的想法是使用(仅向前轴)XPath注释方法 当SAX解析器位于与其匹配的节点时,它们会被调用。所以用文件

<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网站!

答案 6 :(得分:2)

有基于SAX / StAX的XPath实现,但是它们仅支持一小部分XPath表达式/轴,这主要归功于SAX / StAX的前向性......我所知道的最佳替代方案是扩展VTD-XML,它支持完整的xpath,通过mem-map加载部分文档..最大文档大小为256GB,但是你需要64位JVM来充分发挥它的潜力

答案 7 :(得分:2)

对于迟到的回答感到抱歉,但我确实为SAX解析器实现了simple XPath expression路径。由于SAX的前向性,它仅支持tag,带有可选值的属性和索引。当Handler实现delegate Handler时,我用ExpressionFilter来评估给定的表达式。虽然这些类嵌入到项目中,但提取起来并不难。

More information

Examples - 查看带有HandlerHtml前缀

的类

答案 8 :(得分:1)

您可以做的是将XSL转换器挂钩到SAX输入源。您的处理将是顺序的,并且XSL预处理器将尝试捕获输入,因为它将其转换为您指定的任何结果。您可以使用它从流中提取路径的值。如果你想在一次传递中产生一堆不同的XPATH结果,这将特别方便。

结果会得到(通常)一个XML文档,但是你可以把你的预期输出从StreamResult拉出来,而不是太麻烦。

答案 9 :(得分:1)

查看Saxon-SA XSLT处理器的流模式。

http://www.saxonica.com/documentation/sourcedocs/serial.html

“确定路径表达式是否可以流式传输的规则是:

  • 要流式传输的表达式首先调用document()或doc()函数。
  • 对doc()或文档的调用引入的路径表达式必须符合如下定义的XPath子集:

  • 如果任何XPath表达式符合XML Schema中出现在标识约束中的路径表达式的规则,则它是可接受的。这些规则不允许谓词;第一步(但只有第一步)可以用“//”引入;最后一步可以选择使用属性轴;所有其他步骤必须是使用子轴的简单轴步骤。

  • 此外,Saxon允许表达式包含一个联合,例如doc()/(* / ABC | / XYZ)。工会也可以缩写形式表示,例如上面的文字可以写成doc()/ /(ABC | XYZ)。
  • 表达式必须只选择元素,或仅选择属性,或者元素和属性的混合。

  • 还支持简单过滤器(一个或多个)。每个过滤器可以应用于最后一步或整个表达式,并且它只能使用从上下文节点(自身,子,属性,后代,后代或自我或命名空间轴)向下选择。它不能是位置的(也就是说,它不能引用position()或last(),并且不能是数字:事实上,它必须是Saxon可以在编译时确定它不是数字)。过滤器不能应用于工会或工会分支。任何违反这些条件的行为都会导致在没有流优化的情况下评估表达式。

  • 在对表达式应用其他优化重写后,这些规则适用。例如,某些FLWOR表达式可能会被重写为满足这些规则的路径表达式。

  • 只有在显式请求时才能启用优化,方法是使用saxon:stream()扩展函数,或者在XSLT xsl:copy-of指令或XQuery pragma saxon上使用saxon:read-once属性:流。仅当使用Saxon-SA处理样式表或查询时,它才可用。“

注意:最有可能在商业版本中提供此功能。我之前已经广泛使用过Saxon,这是一件很棒的工作。

答案 10 :(得分:0)

是的,我不知道我是否真的了解你。据我所知,SAX模型是面向事件的。这意味着,如果在解析过程中遇到某个节点,则会执行某些操作。是的,它对内存更好,但我不知道你希望如何让XPath进入它。由于SAX没有建立模型,我认为这是不可能的。

答案 11 :(得分:0)

标准的javax xpath API在技术上已经适用于流; javax.xml.xpath.XPathExpression可以针对InputSource进行评估,Reader可以使用{{1}}进行构建。我不认为它构建了一个DOM。

答案 12 :(得分:0)

您是否也尝试过QuiXPath https://code.google.com/p/quixpath/

答案 13 :(得分:-1)

我认为xpath不适用于SAX,但你可以看一下StAX,这是一个用于Java的扩展流XML API。

http://en.wikipedia.org/wiki/StAX

相关问题