调用format-number XPath函数报错:需Namespace Manager或XsltContext
解决XPathEvaluate中使用format-number函数抛出的XPathException问题
嘿,我刚好碰到过类似的问题!你在C#里用XPathEvaluate调用format-number时出现的Namespace Manager or XsltContext needed异常,本质是因为这个函数不是核心XPath的一部分——它属于XSLT 1.0定义的扩展函数,默认的XPath上下文压根不认识它。下面给你一步一步解决的办法:
第一步:自定义XsltContext来支持format-number
我们需要写一个继承自XsltContext的类,用来处理这个扩展函数的解析和执行逻辑:
using System; using System.Xml; using System.Xml.XPath; using System.Xml.Xsl; public class CustomXsltContext : XsltContext { public CustomXsltContext(NameTable nt) : base(nt) { } // 我们不需要处理变量,直接返回null public override IXsltContextVariable ResolveVariable(string prefix, string name) { return null; } // 识别并返回format-number函数的实现 public override IXsltContextFunction ResolveFunction(string prefix, string name, XPathResultType[] ArgTypes) { if (string.Equals(name, "format-number", StringComparison.OrdinalIgnoreCase)) { return new FormatNumberFunction(); } throw new XPathException($"不支持的函数:{name}"); } // 忽略空白保留逻辑,返回false即可 public override bool PreserveWhitespace(XPathNavigator node) { return false; } // 文档比较默认按字符串顺序处理 public override int CompareDocument(string baseUri, string nextbaseUri) { return string.Compare(baseUri, nextbaseUri, StringComparison.Ordinal); } } // 实现format-number的具体逻辑 public class FormatNumberFunction : IXsltContextFunction { // 定义函数的参数类型:数字 + 格式字符串 public XPathResultType[] ArgTypes => new[] { XPathResultType.Number, XPathResultType.String }; public int Maxargs => 2; public int Minargs => 2; public XPathResultType ReturnType => XPathResultType.String; public object Invoke(XsltContext xsltContext, object[] args, XPathNavigator docContext) { if (args[0] is IConvertible numberInput && args[1] is string formatStr) { // 用不变文化确保格式解析一致 return numberInput.ToString(formatStr, System.Globalization.CultureInfo.InvariantCulture); } throw new XPathException("format-number需要两个参数:数字类型的值和格式字符串"); } }
第二步:在代码中使用自定义上下文执行XPath
接下来修改你的原有代码,改用XPathNavigator的Evaluate方法并传入我们的自定义上下文:
XElement test = new XElement("test", 12); var nameTable = new NameTable(); var customContext = new CustomXsltContext(nameTable); // 把XElement转换成XPathNavigator XPathNavigator navigator = test.CreateNavigator(); // 传入自定义上下文执行表达式 object output = navigator.Evaluate("format-number(2, \"00\")", customContext); // 这里会输出"02" Console.WriteLine(output);
补充说明
核心XPath 1.0只包含像concat、substring这类基础函数,format-number是XSLT为了格式化输出额外增加的函数,所以.NET的默认XPath上下文不会加载它。通过自定义XsltContext,我们相当于告诉程序“这个函数该怎么执行”,从而解决异常问题。
内容的提问来源于stack exchange,提问作者Andrew Bennet
相关产品推荐
相关产品推荐

