C# 如何以编程方式在 XPathExpression 实例中使用 XPath 函数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/402211/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 02:05:51  来源:igfitidea点击:

How to use XPath function in a XPathExpression instance programatically?

c#xmlxpathnamespaces

提问by Morgan Cheng

My current program need to use programatically create a XPathExpression instance to apply to XmlDocument. The xpath needs to use some XPath functions like "ends-with". However, I cannot find a way to use "ends-with" in XPath. I

我当前的程序需要以编程方式使用创建一个 XPathExpression 实例来应用到 XmlDocument。xpath 需要使用一些 XPath 函数,比如“ends-with”。但是,我找不到在 XPath 中使用“ends-with”的方法。一世

It throw exception like below

它抛出如下异常

Unhandled Exception: System.Xml.XPath.XPathException: Namespace Manager or XsltC ontext needed. This query has a prefix, variable, or user-defined function.
at MS.Internal.Xml.XPath.CompiledXpathExpr.get_QueryTree() at System.Xml.XPath.XPathNavigator.Evaluate(XPathExpression expr, XPathNodeIt erator context)
at System.Xml.XPath.XPathNavigator.Evaluate(XPathExpression expr)

未处理的异常:System.Xml.XPath.XPathException:需要命名空间管理器或 XsltC ontext。此查询具有前缀、变量或用户定义的函数。
在 MS.Internal.Xml.XPath.CompiledXpathExpr.get_QueryTree() 在 System.Xml.XPath.XPathNavigator.Evaluate(XPathExpression expr, XPathNodeIt erator context)
在 System.Xml.XPath.XPathNavigator.Evaluate(XPathExpression expr)

The code is like this:

代码是这样的:

    XmlDocument xdoc = new XmlDocument();
    xdoc.LoadXml(@"<?xml version=""1.0"" encoding=""utf-8"" ?>
                        <myXml xmlns=""http://MyNamespace"" xmlns:fn=""http://www.w3.org/2005/xpath-functions""> 
                        <data>Hello World</data>
                    </myXml>");
    XPathNavigator navigator = xdoc.CreateNavigator();

    XPathExpression xpr;
    xpr = XPathExpression.Compile("fn:ends-with(/myXml/data, 'World')");

    object result = navigator.Evaluate(xpr);
    Console.WriteLine(result);

I tried to change the code to insert XmlNamespaceManager when compiling the expression, like below

我试图在编译表达式时更改代码以插入 XmlNamespaceManager,如下所示

    XmlDocument xdoc = new XmlDocument();
    xdoc.LoadXml(@"<?xml version=""1.0"" encoding=""utf-8"" ?>
                        <myXml xmlns=""http://MyNamespace"" xmlns:fn=""http://www.w3.org/2005/xpath-functions""> 
                        <data>Hello World</data>
                    </myXml>");
    XPathNavigator navigator = xdoc.CreateNavigator();
    XmlNamespaceManager nsmgr = new XmlNamespaceManager(xdoc.NameTable);
    nsmgr.AddNamespace("fn", "http://www.w3.org/2005/xpath-functions");

    XPathExpression xpr;
    xpr = XPathExpression.Compile("fn:ends-with(/myXml/data, 'World')", nsmgr);

    object result = navigator.Evaluate(xpr);
    Console.WriteLine(result);

It fails on XPathExpression.Compile invocation:

它在 XPathExpression.Compile 调用上失败:

Unhandled Exception: System.Xml.XPath.XPathException: XsltContext is needed for this query because of an unknown function. at MS.Internal.Xml.XPath.CompiledXpathExpr.UndefinedXsltContext.ResolveFuncti on(String prefix, String name, XPathResultType[] ArgTypes) at MS.Internal.Xml.XPath.FunctionQuery.SetXsltContext(XsltContext context) at MS.Internal.Xml.XPath.CompiledXpathExpr.SetContext(XmlNamespaceManager nsM anager) at System.Xml.XPath.XPathExpression.Compile(String xpath, IXmlNamespaceResolv er nsResolver)

未处理的异常:System.Xml.XPath.XPathException:由于未知函数,此查询需要 XsltContext。在 MS.Internal.Xml.XPath.CompiledXpathExpr.UndefinedXsltContext.ResolveFuncti on(String prefix, String name, XPathResultType[] ArgTypes) 在 MS.Internal.Xml.XPath.FunctionQuery.SetXsltContext(XsltContext context) 在 MS.Internal.Xml。 XPath.CompiledXpathExpr.SetContext(XmlNamespaceManager nsM anager) 在 System.Xml.XPath.XPathExpression.Compile(String xpath, IXmlNamespaceResolv er nsResolver)

Anybody know the trick to use off-the-shelf XPath functions with XPathExpression.Compile? Thanks

有人知道在 XPathExpression.Compile 中使用现成的 XPath 函数的技巧吗?谢谢

采纳答案by Dimitre Novatchev

The functionends-with()is not defined for XPath 1.0but only for XPath 2.0and XQuery.

该函数不是为XPath 1.0定义的,而是只为XPath 2.0XQuery 定义的ends-with()

You are using .NET. .NET at this date does not implementXPath 2.0, XSLT 2.0or XQuery.

您正在使用 .NET。. NET 目前尚未实现XPath 2.0XSLT 2.0XQuery

One can easily construct an XPath 1.0 expression, the evaluation of which produces the same result as the function ends-with():

可以很容易地构造一个 XPath 1.0 表达式,它的计算产生与函数相同的结果ends-with()

$str2 = substring($str1, string-length($str1)- string-length($str2) +1)

$str2 = substring($str1, string-length($str1)- string-length($str2) +1)

produces the same boolean result (true()or false()) as:

产生与以下相同的布尔结果 ( true()or false()):

ends-with($str1, $str2)

ends-with($str1, $str2)

In your concrete case you just need to substitute the right expressions for $str1and $str2. They are, accordingly, /myXml/dataand 'World'.

在您的具体情况下,您只需要为$str1and替换正确的表达式$str2。因此,它们是/myXml/data'World'

So, the XPath 1.0 expression to use, that is equivalent to the XPath 2.0 expression ends-with(/myXml/data, 'World')is:

因此,要使用的 XPath 1.0 表达式,即等效于 XPath 2.0 表达式ends-with(/myXml/data, 'World')

'World' = 
   substring(/myXml/data,
             string-length(/myXml/data) - string-length('World') +1
             )