多节点XPath子串选择在C#中提示无效令牌问题求助
问题:C#中执行XPath字符串处理表达式报“无效令牌”错误
原始XML文档
<Comments> <Comment>09/28/2021 22:21:31user1 [1] file uploaded </Comment> <Comment>09/28/2021 22:22:47user2 [2] file scanned</Comment> <Comment>09/28/2021 22:23:15user3 [3] Backed up before edit</Comment> <Comment>09/28/2021 22:23:39user3 [4] file edited </Comment> </Comments>
需求与原始XPath表达式
需要从每个Comment节点中分别提取三类信息,对应的原始XPath表达式如下:
- 提取时间戳:
/Comments/Comment/fn:substring(text(), 0, 20) - 提取用户ID:
/Comments/Comment/fn:substring(text(), 20, string-length(substring-before(text(), "[")) - 20) - 提取评论内容:
/Comments/Comment/fn:substring-after(text(), "]")
上述表达式在XPath测试器中可正常运行,但在C#代码中执行时返回“无效令牌”错误。
尝试的两种C#实现方式
方式一:使用XmlDocument.SelectNodes
var list = new List<XmlNodeList>(); var nodes = doc.SelectNodes(strExpression); if (nodes.Count > 0) { list.Add(nodes); }
方式二:使用XPathNodeIterator
XPathNodeIterator NodeIter; NodeIter = nav.Select(strExpression); while (NodeIter.MoveNext()) { if (NodeIter.Current != null) xpathValue.Add(NodeIter.Current.Value); };
解决方案
错误核心原因是:.NET框架默认支持XPath 1.0,而fn:前缀是XPath 2.0及后续版本的命名空间写法,XPath 1.0中不需要添加该前缀,直接使用函数名即可。同时XPath 1.0的字符串索引从1开始,原表达式的索引值需做对应调整。
修正后的XPath表达式如下:
- 提取时间戳:
/Comments/Comment/substring(text(), 1, 19)
注:时间戳格式
09/28/2021 22:21:31共19个字符,XPath 1.0中从索引1开始截取19位即可准确获取
- 提取用户ID:
/Comments/Comment/substring(text(), 20, string-length(substring-before(text(), "[")) - 19)
注:调整长度计算逻辑,匹配XPath 1.0的索引规则,确保截取到
[之前的用户ID内容
- 提取评论内容:
/Comments/Comment/substring-after(text(), "]")
使用修正后的表达式,两种C#实现方式均可正常执行。若需使用XPath 2.0特性,可引入第三方库(如Saxon-HE)替代.NET原生XML处理API。
内容的提问来源于stack exchange,提问作者Aysha Khan
相关产品推荐
相关产品推荐

