You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:37:17