2010-04-21 90 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检查得到更简洁。