简洁的LINQ to XML查询

3
假设您有以下XML:

假设您有以下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个回答

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

试一下吧 :)


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

也许我应该更明确地说:“不使用XPath”。我很清楚XPath更加简洁,但需要一些说服才能不切换到它。谢谢。 - Kent Boogaart
@Kent Boogaart:抱歉,我误解了你的问题。 - Gregoire

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

如果空值检查是首要任务(看起来确实是这样):
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 检查。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接