2010-04-21 91 views
3

假設你有以下的XML:簡潔的LINQ to XML查詢

<?xml version="1.0" encoding="utf-8"?> 

<content> 
    <info> 
     <media> 
      <image> 
       <info> 
        <imageType>product</imageType> 
       </info> 
       <imagedata fileref="http://www.example.com/image1.jpg" /> 
      </image> 
      <image> 
       <info> 
        <imageType>manufacturer</imageType> 
       </info> 
       <imagedata fileref="http://www.example.com/image2.jpg" /> 
      </image> 
     </media> 
    </info> 
</content> 

使用LINQ to XML,什麼是最簡潔的,可靠的方法來獲得System.Uri給定類型的圖像?目前我有這個:

private static Uri GetImageUri(XElement xml, string imageType) 
{ 
    return (from imageTypeElement in xml.Descendants("imageType") 
      where imageTypeElement.Value == imageType && imageTypeElement.Parent != null && imageTypeElement.Parent.Parent != null 
      from imageDataElement in imageTypeElement.Parent.Parent.Descendants("imagedata") 
      let fileRefAttribute = imageDataElement.Attribute("fileref") 
      where fileRefAttribute != null && !string.IsNullOrEmpty(fileRefAttribute.Value) 
      select new Uri(fileRefAttribute.Value)).FirstOrDefault(); 
} 

這樣的工作,但感覺過於複雜。特別是當你考慮XPath等價物時。

任何人都可以指出一個更好的方法嗎?

回答

1
var images = xml.Descentants("image"); 

return images.Where(i => i.Descendants("imageType") 
          .All(c => c.Value == imageType)) 
      .Select(i => i.Descendants("imagedata") 
          .Select(id => id.Attribute("fileref")) 
          .FirstOrDefault()) 
      .FirstOrDefault(); 

給一個去:)

+0

+1謝謝,但它仍然比XPath等效更詳細... – 2010-04-22 08:08:49

1
return xml.XPathSelectElements(string.Format("//image[info/imageType='{0}']/imagedata/@fileref",imageType)) 
.Select(u=>new Uri(u.Value)).FirstOrDefault(); 
+0

也許我應該更明確地說:「不使用XPath」。我很清楚XPath更簡潔,並且需要一些令人信服的信息才能切換到它。不過謝謝。 – 2010-04-21 16:25:19

+0

@Kent Boogaart:對不起,我誤解了你的問題 – Gregoire 2010-04-21 16:27:36

0

如果你能保證該文件將始終有相關的數據,然後用無類型檢查:

private static Uri GetImageUri(XElement xml, string imageType) 
{ 
    return (from i in xml.Descendants("image") 
      where i.Descendants("imageType").First().Value == imageType 
      select new Uri(i.Descendants("imagedata").Attribute("fileref").Value)).FirstOrDefault(); 
} 

如果null檢查是一個優先事項(似乎是這樣):

private static Uri GetSafeImageUri(XElement xml, string imageType) 
{ 
    return (from i in xml.Descendants("imagedata") 
      let type = i.Parent.Descendants("imageType").FirstOrDefault() 
      where type != null && type.Value == imageType 
      let attr = i.Attribute("fileref") 
      select new Uri(attr.Value)).FirstOrDefault(); 
} 

不確定您是否會比使用null檢查得到更簡潔。