c# - 使用 XPathEvaluate 获取 Linq-to-Xml 查询中的文本节点值

标签 c# xpath linq-to-xml

我最近遇到了一种情况,我必须使用 XPath 作为 Linq to XML 查询的一部分,并发现它的行为有点奇怪。我确信还有其他方法可以使用 native XElement API 方法来解决问题,但在这种情况下,XPath 更适合定位我需要的特定 XML 文本值,因为文档结构相当复杂。我最终找到了一种让它工作的方法(见下文),但它不是很漂亮,这通常意味着我错过了一些东西。

我的问题是如何使用XPathEvalute或其他一些 XPath 方法返回一个字符串值,该值可在 where 语句中使用或作为 select 方法中新对象的一部分。我找到了一个使用大量类型转换的解决方案,并且 Null coalesing operator in LINQ ,但必须有一种更清洁的方法。问题的根源在于 XPathEvaluate 方法通常会返回 XText 元素(转换为通用对象),但 Linq 将其转换为 IEnumerable,以便延迟执行。当您尝试访问该对象的值时,这会导致问题,因为在执行查询之前它不会具体化。

示例如下:使用以下 XML 文档查找具有相同名字的男孩和女孩的所有 parent 。这必须使用 XPath 查询来完成,因为在我的情况下,文档结构非常复杂。

//Use C# Program Language type in LinqPad
void Main()
{
    var xml = XElement.Parse(@"<Root>
        <Parent>
            <Boy>Anne</Boy>
        </Parent>
        <Parent>
            <Boy>Alex</Boy>
            <Girl>Alex</Girl>
        </Parent>
        <Parent>
            <Boy>Jay</Boy>
        </Parent>
    </Root>");

    var q1 = from e in xml.XPathSelectElements("/Parent")
             select e;

    q1.Dump();

    var q2 = from e in q1
             let boy = ((IEnumerable<Object>)e.XPathEvaluate("Boy/text()")).Cast<System.Xml.Linq.XText>().FirstOrDefault() ?? new System.Xml.Linq.XText("")
             let girl = ((IEnumerable<Object>)e.XPathEvaluate("Girl/text()")).Cast<System.Xml.Linq.XText>().FirstOrDefault() ?? new System.Xml.Linq.XText("")
             select new {t=boy.GetType(), b=boy, g=girl, same=(boy.Value==girl.Value)};

    q2.Dump();
}

结果是:

enter image description here

您可以看到第二个元素被识别为具有同名的男孩和女孩。在仍然使用 XPath 的同时是否有更简洁的方法来执行此操作,或者我是否坚持使用上面的代码。

最佳答案

使用 XPathSelectElement 代替 XPathEvaluate 是否可以接受?

var q2 = from e in q1
         let boy = (string)e.XPathSelectElement("Boy")
         let girl = (string)e.XPathSelectElement("Girl")
         where boy.StartsWith("A") //Optional use in where statement
         select new { t = boy.GetType(), b = boy, g = girl, same = (boy == girl) };

关于c# - 使用 XPathEvaluate 获取 Linq-to-Xml 查询中的文本节点值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10033212/

相关文章:

python xml查询获取父级

xslt - 具有命名空间的元素上的 xpath 选择

xml - XPath基于复杂过滤器统计子节点

vb.net - VB Linq中的“New…With”语法有什么作用?

c# - 在具有 ui/非 ui 线程差异的 WPF 中使用 PInvoke

c# - WebAPI XML 格式化程序不返回所有字段

c# - Linq to XML 可以使用冒号吗?

c# - 选择和跳过元素

c# - .NET C# 中的简单 OCR 问题

c# - 如何从 JavaScript/C# 生成宽度 CSS