【发布时间】:2021-01-18 13:11:58
【问题描述】:
在我的 C# 程序 (.NET Framework 4.8) 中,我在运行时创建了一个 XDocument。我需要针对这个 XML 树在运行时执行几个 XQuery 评估。相应的查询来自外部来源,所以我在设计时不知道它们的细节。查询可能包含 exists()、not()、empty() 或 every $x in ... satiesfies ... 或 generate-id() 等函数。
作为第一步,我真正需要知道的是查询是否产生结果(即从 XDocument 返回的 something 不为空)。
最初,我只是尝试使用 XElement.XPathEvaluate(query),只要所述查询真的只是 XPath 评估,它就可以正常工作 - 但如果它包含函数 - 如 exists(...) 等 - 会抛出一个错误,告诉我我需要一个 XsltContext。我有的是:
public bool XPathExists(string context, string xpath)
{
Object result;
try
{
XElement contextElement = xmlTree.Root.XPathSelectElement(context, namespaces);
result = contextElement.XPathEvaluate(xpath, namespaces);
}
catch (Exception e) // xpath can't be evaluated
{
Debug.Print(e.Message);
return false;
}
return (result != null);
}
所以我认为我需要使用 Saxon-HE 来执行查询,因为它完全支持 XQuery。不幸的是,我很难正确初始化 Saxon 的 XQueryEvaluator,并使用内存中的 XDocument 作为源(或者根本就使用它)。此外,令人沮丧的是,我不知道在哪里/如何向 Saxon 提供要在其中评估 xquery 的初始上下文节点。无论是阅读the API documentation,还是 Michael Kay 的书“XSLT 2.0 和 XPath 2.0”中关于将 Saxon 与 .NET 结合使用的章节,也没有一般地搜索互联网(尤其是 StackOverflow),都没有让我有所收获。
到目前为止,我一直坚持使用这个(当然是不工作的)“代码”:
public bool XQueryYieldsResults(XDocument xmlTree, string contextNode, string xqueryExpression)
{
var processor = new Processor();
XdmNode input = processor.NewDocumentBuilder().Build(xmlTree);
var compiler = processor.NewXQueryCompiler();
var exececutable = compiler.Compile(xqueryExpression); // how to set context?
var xqueryEvaluator = exececutable.Load(); // ...?!
// ...
// var result = *the xquery's result*;
// ...
return (result != null);
}
对不起,我真的不知道从哪里开始!任何关于在这里做什么的提示 - 或者更具体地说:如何使用 Saxon-HE 对 XDocument 执行具有给定上下文的 XQuery - 将不胜感激! :-)
【问题讨论】:
-
@MartinHonnen 和@jdweng 正确地指出,Saxon(当前)没有能力直接针对 XML 的 XDocument 树模型运行;使用它的唯一方法是将其重建为 DOM 文档 (
XmlDocument) 或 Saxon TinyTree。 -
感谢您指出这一点。
标签: c# xml linq-to-xml xquery saxon