我最近發現一種情況,我必須將XPath用作Linq to XML查詢的一部分,並發現它有點奇怪。我確信還有其他解決使用本機XElement API方法的問題的方法,但在這種情況下,XPath更適合查找我需要的特定XML文本值,因爲文檔結構非常複雜。我最終找到了一種使其工作的方式(見下文),但它不是很漂亮,通常意味着我錯過了一些東西。使用XPathEvaluate在Linq-to-Xml查詢中獲取文本節點值
我的問題是如何使用XPathEvalute或其他一些XPath方法來返回一個字符串值,該值可以在where語句中使用,也可以在select方法中作爲新對象的一部分使用。我找到了一個解決方案,它使用了大量的鑄件和Null coalesing operator in LINQ,但必須有一個更清潔的方法。問題的根源在於XPathEvaluate方法通常會返回一個XText元素(轉換爲通用對象),但Linq將其轉換爲IEnumerable,以便延遲執行。當您嘗試訪問該對象的值時,這會導致問題,因爲在執行查詢之前它沒有實現。
下面是示例:使用以下XML文檔查找所有擁有同名男孩和女孩的父母。這必須使用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();
}
結果是:
你可以看到第二個元素標識爲具有相同名稱的男孩和女孩。在使用XPath的時候還有更乾淨的方法嗎?或者我堅持使用上面的代碼。
您可以簡化您的XPath來獲取所有與你正在尋找標準的家長://父[男/文()=女孩/文()] – JWiley 2012-04-05 18:00:16