流式 XPath 评估
Posted
技术标签:
【中文标题】流式 XPath 评估【英文标题】:Streaming XPath evaluation 【发布时间】:2010-11-03 00:35:33 【问题描述】:是否有任何生产就绪库可用于针对提供的 xml 文档进行流式 XPath 表达式评估?我的调查表明,大多数现有解决方案在评估 xpath 表达式之前会将整个 DOM 树加载到内存中。
【问题讨论】:
非常感谢,我以前看过你的项目。看起来很有希望 有一些关于这个主题的新信息——见我的回答。 【参考方案1】:我想我会选择自定义代码。如果只想读取 xml 文档的一些路径,.NET 库让我们非常接近目标。
由于到目前为止我看到的所有解决方案都只考虑 XPath 子集,所以这也是这种解决方案。虽然子集真的很小。 :)
此 C# 代码读取 xml 文件并计算给定显式路径的节点。您还可以使用xr["attrName"]
语法轻松地对属性进行操作。
int c = 0;
var r = new System.IO.StreamReader(asArgs[1]);
var se = new System.Xml.XmlReaderSettings();
var xr = System.Xml.XmlReader.Create(r, se);
var lstPath = new System.Collections.Generic.List<String>();
var sbPath = new System.Text.StringBuilder();
while (xr.Read())
//Console.WriteLine("type " + xr.NodeType);
if (xr.NodeType == System.Xml.XmlNodeType.Element)
lstPath.Add(xr.Name);
// It takes some time. If 1 unit is time needed for parsing the file,
// then this takes about 1.0.
sbPath.Clear();
foreach(object n in lstPath)
sbPath.Append('/');
sbPath.Append(n);
// This takes about 0.6 time units.
string sPath = sbPath.ToString();
if (xr.NodeType == System.Xml.XmlNodeType.EndElement
|| xr.IsEmptyElement)
if (xr.Name == "someElement" && lstPath[0] == "main")
c++;
// And test simple XPath explicitly:
// if (sPath == "/main/someElement")
if (xr.NodeType == System.Xml.XmlNodeType.EndElement
|| xr.IsEmptyElement)
lstPath.RemoveAt(lstPath.Count - 1);
xr.Close();
【讨论】:
【参考方案2】:虽然我没有实践经验,但我认为值得一提的是 QuiXProc (http://code.google.com/p/quixproc/)。它是 XProc 的一种流式处理方法,并使用为 XPath 等提供流式传输支持的库。
【讨论】:
【参考方案3】:XSLT 3.0 提供streaming mode of processing,随着 XSLT 3.0 W3C 规范成为 W3C 推荐标准,这将成为一个标准。
在撰写此答案时(2011 年 5 月),Saxon 提供了一些 support for XSLT 3.0 streaming。
【讨论】:
【参考方案4】:FWIW,我对非常大 (>3GB) 的文件使用了 Nux 流式过滤器 xpath 查询,它既可以完美运行,也可以使用很少的内存。我的用例略有不同(不是以验证为中心),但我强烈建议您尝试使用 Nux。
【讨论】:
【参考方案5】:有几种选择:
DataDirect Technologies sells an XQuery implementation 在可能的情况下采用投影和流式传输。它可以处理数千兆字节范围内的文件 - 例如大于可用内存。它是一个线程安全的库,因此很容易集成。仅限 Java。
Saxon 是一个开源版本,有一个价格适中的更昂贵的表亲,它可以在某些情况下进行流式传输。 Java,但也有一个 .net 端口。
MarkLogic 和 eXist 是 XML 数据库,如果将您的 XML 加载到其中,它们将以相当智能的方式处理 XPath。
【讨论】:
【参考方案6】:试试Joost。
【讨论】:
【参考方案7】:这对于完整的 XPath 实现是否实用,因为 XPath 语法允许:
/AAA/XXX/following::*
和
/AAA/BBB/following-sibling::*
这意味着前瞻性要求?即,无论如何您都必须从特定节点加载文档的其余部分。
Nux 库(特别是 StreamingPathFilter)的文档说明了这一点,并引用了一些依赖于 XPath 子集的实现。 Nux 声称可以执行一些流式查询功能,但鉴于上述情况,在 XPath 实现方面会有一些限制。
【讨论】:
实际上我需要执行简单的 xpath 查询来检查给定 xml 文档中的多个节点以进行验证。 XML 文档代表一个实体,它的一些节点存储其他实体的外键。因此,应该对这些特殊节点应用某种完整性验证。整个文档非常大,在内存中存储如此大量的数据以执行几个简单的 xpath 查询将是低效的。 看起来 Nux 库很可能在这种情况下为您提供帮助。或者,您是否可以使用 Stax 库并将 XPath 应用于从某个节点提取的本地 XML 文档? 其实我不能采用第二种方法,因为xml文档的结构比较简单,撕掉文档的某个节点并对其应用evaluate xpath表达式是没有意义的。 我想我现在会尝试 XOM。 @Brian 谢谢你的建议,我很感激。以上是关于流式 XPath 评估的主要内容,如果未能解决你的问题,请参考以下文章