【发布时间】:2018-03-13 17:42:39
【问题描述】:
我编写了一个 C# 应用程序来解析非常大 (100MB+) 的 XML 文件。
我完成它的方法是使用System.Xml.XmlReader 遍历文件,然后,一旦到达需要从中收集值的最终节点,我将每个非常小的元素转换为System.Xml.Linq.XElement并通过XEelement.XPathEvaluate 执行各种XPath 语句来获取我需要的数据。
这工作得非常好且高效,但我遇到了一个问题,有时我会收到错误的数据,因为XPathEvaluate 仅支持 XPath 1.0 而我的声明是 XPath 2.0(问题已发布here)。
我最初执行此操作的代码如下所示:
void parseNode_Old(XmlReader rdr, List<string> xPathsToExtract)
{
// Enter the node:
rdr.Read();
// Load it as an XElement so as to be able to evaluate XPaths:
var nd = XElement.Load(rdr);
// Loop through the XPaths related to that node and evaluate them:
foreach (var xPath in xPathsToExtract)
{
var xPathVal = nd.XPathEvaluate(xPath);
// Do whatever with the extracted value(s)
}
}
按照我上一个问题中给出的建议,我决定最好的解决方案是从 System.Xml 移动到 Saxon.Api(它确实支持 XPath 2.0),我当前更新的代码如下所示:
void parseNode_Saxon(XmlReader rdr, List<string> xPathsToExtract)
{
// Set up the Saxon XPath processors:
Processor processor = new Processor(false);
XPathCompiler compiler = processor.NewXPathCompiler();
XdmNode nd = processor.NewDocumentBuilder().Build(rdr);
// Loop through the XPaths related to that node and evaluate them:
foreach (var xPath in xPathsToExtract)
{
var xPathVal = compiler.EvaluateSingle(xPath, (XdmNode)childNode);
// Do whatever with the extracted value(s)
}
}
这是可行的(对我的 XPath 进行了一些其他更改),但它变得慢了大约 5-10 倍。
这是我第一次使用 Saxon.Api 库,这也是我想出的。我希望有更好的方法来实现这一点,以使代码执行速度具有可比性,或者,如果有人对如何以更好的方式评估 XPath 2.0 语句而无需大量重写有其他想法,我很想听听他们!
任何帮助将不胜感激!
谢谢!!
更新:
在尝试自己解决此问题时,我将以下 2 条语句移至构造函数:
Processor processor = new Processor(false);
XPathCompiler compiler = processor.NewXPathCompiler();
而不是在每次调用此方法时不断地重新创建它们,这有很大帮助,但该过程仍然比本机 System.Xml.Linq 版本慢约 3 倍。关于如何实现这个解析器的任何其他想法/想法?
【问题讨论】:
标签: c# xml xpath xml-parsing saxon