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

使用C# XPathNavigator执行XPath if-then-else表达式时为何报无效令牌错误?

这个问题我之前也碰到过!根源在于.NET原生的XPathExpression默认只支持XPath 1.0,而你写的if(//DovizCins = 'YTL') then '1' else '2'是XPath 2.0的条件语法,XPath 1.0根本不认识这种写法,所以才会抛出无效令牌的异常。

接下来给你两种解决方案:


方案一:用XPath 1.0的等效语法实现

XPath 1.0没有直接的三元运算符,但可以通过substring结合布尔值隐式转换来实现相同逻辑。把你的表达式改成下面这样就行:

var expression = "substring('12', 1 + boolean(not(//DovizCins = 'YTL')), 1)";
var nav = doc.CreateNavigator();
XPathExpression xp = XPathExpression.Compile(expression);
var value = nav.Evaluate(xp);
return value?.ToString() ?? string.Empty;

我给你拆解一下这个表达式的逻辑:

  • //DovizCins = 'YTL':检查XML中是否存在任意一个DovizCins节点的值等于YTL
  • not(...):对上面的结果取反,当没有匹配的节点时返回true
  • boolean(...):把结果转为布尔值,XPath中true会被隐式转成数字1,false转成0
  • substring('12', 起始位置, 1):从字符串'12'里截取1个字符——如果条件成立(找到匹配节点),起始位置是1+0=1,取到'1';如果条件不成立,起始位置是1+1=2,取到'2'

方案二:启用XPath 2.0支持(需第三方库)

如果你一定要用XPath 2.0的原生语法,可以使用开源的Saxon-HE库(这是.NET生态中支持XPath 2.0/3.0最成熟的库)。

步骤如下:

  1. 通过NuGet安装Saxon-HE包
  2. 修改代码为:
using Saxon.Api;
using System.Xml.XPath;

// 假设你的原始文档是XmlDocument类型的doc
Processor processor = new Processor();
DocumentBuilder builder = processor.NewDocumentBuilder();
// 把XmlDocument转成Saxon能处理的XdmNode
XdmNode saxonDoc = builder.Build(new XmlNodeWrapper(doc));

// 编译XPath 2.0表达式
XPathCompiler compiler = processor.NewXPathCompiler();
XPathExecutable executable = compiler.Compile("if(//DovizCins = 'YTL') then '1' else '2'");

// 执行并获取结果
XPathSelector selector = executable.Load();
selector.ContextItem = saxonDoc;
XdmValue result = selector.Evaluate();

return result.ToString() ?? string.Empty;

一般来说,方案一足够解决你的需求,不需要额外引入第三方依赖。如果后续需要更复杂的XPath语法(比如循环、字符串处理函数等),再考虑方案二。

内容的提问来源于stack exchange,提问作者mesut

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 22:22:33