如何在XmlNode后代元素中用starts-with进行节点筛选?
如何正确使用XPath的
starts-with筛选后代元素? 首先直接给结论:你当前修正后的XPath表达式不正确,核心问题是拼写错误——你把目标前缀author_误写成了MeritCriterion_,这会导致完全匹配不到你想要的作者节点。
正确的XPath表达式写法
针对每个book节点,要筛选其后代中名称以author_开头的元素,正确的表达式应该是:
descendant::*[starts-with(local-name(),'author_')]
结合你的C#代码的完整修正示例
这里是修正后的可运行代码,包含遍历book节点并获取对应作者节点的完整逻辑:
XmlDocument submission = new XmlDocument(); submission.LoadXml(xml); // 获取所有名称以book_开头的节点 var bookNodes = submission.SelectNodes("//*[starts-with(local-name(),'book_')]"); foreach (XmlNode book in bookNodes) { // 修正拼写错误,筛选当前book节点下所有以author_开头的后代元素 var bookAuthors = book.SelectNodes("descendant::*[starts-with(local-name(),'author_')]"); // 遍历并处理每个作者节点 foreach (XmlNode author in bookAuthors) { string authorName = author.SelectSingleNode("name").InnerText; string authorAge = author.SelectSingleNode("age").InnerText; // 替换为你需要的业务逻辑 Console.WriteLine($"作者:{authorName},年龄:{authorAge}"); } }
额外细节说明
- 关于
descendant::*:这个轴会匹配当前节点下所有层级的后代元素(不管是直接子节点还是更深嵌套的)。如果你的XML结构里author_永远是book_的直接子节点,也可以简化成*[starts-with(local-name(),'author_')],但descendant::更灵活,能适配未来可能的结构变化。 - 关于
local-name():这个函数用来获取元素的本地名称(不包含命名空间),如果你的XML没有使用命名空间,用name()也可以,但local-name()兼容性更好,能避免命名空间带来的匹配问题。 - 前缀匹配的准确性:
starts-with的第二个参数必须完全匹配目标前缀,拼写错误是这类问题最常见的诱因,一定要仔细核对。
内容的提问来源于stack exchange,提问作者Dhanuka777
相关产品推荐
相关产品推荐

