我编写了一个C应用程序来解析非常大(100MB以上)的XML文件。
我完成它的方式是使用
System.Xml.XmlReader
然后,当我到达需要从中收集值的最终节点时,我将这些非常小的元素转换为
System.Xml.Linq.XElement
并通过执行各种XPath语句
XEelement.XPathEvaluate
获取我需要的数据。
这非常有效,但我遇到了一个问题,有时由于以下事实,我会得到错误的数据
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倍。
这是我第一次与撒克逊人合作。Api库,这就是我想到的。我希望有更好的方法来实现这一点,以使代码执行速度具有可比性,或者,如果有人对如何在不进行大量重写的情况下以更好的方式评估XPath 2.0语句有其他想法,我很乐意听到他们!
任何帮助都将不胜感激!!
谢谢
更新时间:
为了自己解决这个问题,我将以下两条语句移到了构造函数中:
Processor processor = new Processor(false);
XPathCompiler compiler = processor.NewXPathCompiler();
相反,每次调用此方法都会不断地重新创建它们,这有很大的帮助,但过程仍然比本机慢3倍左右
System.Xml.Linq
版本关于实现这个解析器的方法,还有其他想法吗?