【问题标题】:Find an XElement with a certain attribute name and value with LINQ使用 LINQ 查找具有特定属性名称和值的 XElement
【发布时间】:2012-06-14 11:31:00
【问题描述】:
XDocument xDocument = XDocument.Load("...");
IEnumerable<XElement> elements = xDocument
    .Element("lfm")
    .Element("events")
    .Elements("event");

try
{            
    foreach (XElement elm in elements)
    {
        comm.Parameters.AddWithValue("extID", elm.Element("id").Value  ?? "");
        comm.Parameters.AddWithValue("Title", elm.Element("title").Value ?? "");
        comm.Parameters.AddWithValue("HeadlineArtist", 
        elm.Element("artists").Element("headliner").Value ?? "");

但是我想要属性“size=large”的元素“image”的值,我找了一夜,这是我最接近的:

comm.Parameters.AddWithValue("LargeImage",
    elm.Descendants("image")
       .FirstOrDefault(i => (string)i.Attribute("size") == "large").Value);

XML 响应部分示例:

<lfm status="ok">
    <events xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"
            location="Chicago, United States" page="1" perPage="1"
            totalPages="341" total="341" festivalsonly="0" tag="">
        <event xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#">
            <id>3264699</id>
            <title>Iron And Wine</title>
            <artists>
                <artist>Iron And Wine</artist>
                <artist>Dr. John</artist>
                <headliner>Iron And Wine</headliner>
            </artists>
            <venue>
                <id>8915382</id>
                <name>Ravinia Festival</name>
                <location>
                    <city>Highland Park</city>
                    <country>United States</country>
                    <street>200 Ravinia Park Rd</street>
                    <postalcode>60035</postalcode>
                    <geo:point>
                        <geo:lat>42.15831</geo:lat>
                        <geo:long>-87.778409</geo:long>
                    </geo:point>
                </location>
                <url>http://www.last.fm/venue/8915382+Ravinia+Festival</url>
                <website>http://www.ravinia.org/</website>
                <phonenumber>847.266.5100</phonenumber>
                <image size="small">http://userserve-ak.last.fm/serve/34/63026487.jpg</image>
                <image size="medium">http://userserve-ak.last.fm/serve/64/63026487.jpg</image>
                <image size="large">http://userserve-ak.last.fm/serve/126/63026487.jpg</image>
                <image size="extralarge">http://userserve-ak.last.fm/serve/252/63026487.jpg</image>

【问题讨论】:

  • 那么,有什么问题呢?这看起来不错,但这取决于elm 是什么(您没有向您展示如何从 xDocument 到 elm)。
  • 当没有找到具有该属性的元素时,您将获得NullReferenceException

标签: c# xml linq xelement


【解决方案1】:

试试

XElement result = elm.Descendants("image")
   .FirstOrDefault(el => el.Attribute("size") != null &&
                         el.Attribute("size").Value == "large");
if (result != null) {
    process result.Value ...
}

从 C#6.0 (VS 2015) 开始,您可以编写:

XElement result = elm.Descendants("image")
   .FirstOrDefault(el => el.Attribute("size")?.Value == "large");
if (result != null) {
    process result.Value ...
}

一个不明显的替代方案(正如@RandRandom 指出的那样)是将属性转换为string

XElement result = elm.Descendants("image")
   .FirstOrDefault(el => (string)el.Attribute("size") == "large");
if (result != null) {
    process result.Value ...
}

这行得通,因为XAttribute Explicit Conversion (XAttribute to String)

【讨论】:

  • 出于某种原因,起初这不起作用,但现在效果很好!
  • 代替 ?.Value 或 .Value 开头,你可以这样写:(string)el.Attribute("size") == "large"(适用于所有版本)跨度>
【解决方案2】:

你可以使用XPathSelectElement extension method

var node = elm.XPathSelectElement("descendant::image[@size='large']");
if (node!=null)
{
    var path = node.Value;
}

【讨论】:

  • 惊人的答案!。也经过测试并适用于 .NET Core/.NET Standard 1.6!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-06
  • 2014-05-03
  • 2021-06-25
  • 2010-09-22
  • 1970-01-01
相关资源
最近更新 更多