当存在多个匹配项时使用C#XPathSelectElement()

本文关键字:C#XPathSelectElement 存在 | 更新日期: 2023-09-27 18:24:04

我们在我支持的应用程序中得到了意外的结果,因为代码在匹配多个项的路径上调用XPathSelectElement()。举例说明:

XElement e = XElement.Parse(@"<root>
                                <child ID="123">A</child>
                                <child ID="234">B</child>
                              </root>");
Console.Out.WriteLine(e.XPathSelectElement("//child").Value);

在这个简单的例子中,它返回"A"。在我们更复杂的生产代码中,它似乎返回了最后一个匹配项。

为了明确起见,我将在XPath中使用额外的过滤来修复这个错误,以使查询结果唯一。我不想依赖于滥用XPathSelectElement()方法。

但是,我想确保我理解它目前(错误地)在做什么。在这种情况下,我找不到任何关于预期行为的文档。或者这只是一种非标准的行为,您不能期望它在不同的环境/版本等中保持一致?

当存在多个匹配项时使用C#XPathSelectElement()

XPathSelectElements的文档中说(https://msdn.microsoft.com/en-us/library/bb342176%28v=vs.110%29.aspx)"虽然XML XPath Language 1.0建议中没有指定返回集合的顺序,但此扩展方法按文档顺序返回节点。"。XPathSelectElement的实现(http://referencesource.microsoft.com/#System.Xml.Linq/System/Xml/Linq/XNodeNavigator.cs,7b67622e3ab8770e)简单地执行return node.XPathSelectElements(expression, resolver).FirstOrDefault();。因此,基于此,您应该按文档顺序获得第一个选定的child元素的值。如果得到不同的结果,我会认为这是一个错误,但我们需要一个最小但完整的XML和.NET示例,以便我们能够重现结果。

正确的选择是更加具体。如果你总是想要第一个元素,你可以使用XPathSelectElements和first():

    XElement e = XElement.Parse(@"<root>
                                    <child ID=""123"">A</child>
                                    <child ID=""234"">B</child>
                                  </root>");
    Console.Out.WriteLine(e.XPathSelectElements("//child").First().Value);

或者,您可以使用更具体的xpath来获得第一个元素:

    XElement e = XElement.Parse(@"<root>
                                    <child ID=""123"">A</child>
                                    <child ID=""234"">B</child>
                                  </root>");
    Console.Out.WriteLine(e.XPathSelectElement("(//child)[1]").Value);
相关文章:
  • 没有找到相关文章