代码之家  ›  专栏  ›  技术社区  ›  Kent Boogaart

简洁的LINQ to XML查询

  •  3
  • Kent Boogaart  · 技术社区  · 16 年前

    假设您有以下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等价物时。

    有人能指出更好的方法吗?

    3 回复  |  直到 16 年前
        1
  •  1
  •   Aren    16 年前
    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();
    

    试试看:)

        2
  •  1
  •   Gregoire    16 年前
    return xml.XPathSelectElements(string.Format("//image[info/imageType='{0}']/imagedata/@fileref",imageType))
    .Select(u=>new Uri(u.Value)).FirstOrDefault();
    
        3
  •  0
  •   jeffora    16 年前

    如果可以保证文件始终具有相关数据,则不进行类型检查:

    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();
    }
    

    不知道你会不会比这更简洁 无效的 检查。