如何使用“let”来处理缺少的XML节点?

时间:2014-02-08 02:09:11

标签: c# xml linq-to-xml

我在这里根据我原来发布的一些反馈更新了我的问题。我正在尝试解析XDocument中的一些xml而没有得到我期望的结果。根据下面的反馈,我在下面添加了两个let语句,但它们没有按预期工作,我认为我以某种方式弄错了它们。问题是,当XML结果中没有CoverArt和Biography时,我从查询中得不到任何回复这是我正在运行的代码:

public List<Album> ParseResults(XDocument inputDoc)
{
    var albums = new List<Album>();

    try
    {
        albums = (from item in inputDoc.Descendants("ALBUM") 
                  select new Album
                      {

                          let CoverArt = item.Elements("URL").First(u => u.Attribute("TYPE").Value == "COVERART") ?? new XElement("COVERART")
                          let Biography = item.Elements("URL").First(u => u.Attribute("TYPE").Value == "ARTIST_BIOGRAPHY") ?? new XElement("ARTIST_BIOGRAPHY")

                          AlbumId = (string)item.Element("GN_ID"),
                          ArtistName = (string)item.Element("ARTIST"),
                          AlbumName = (string)item.Element("TITLE"),
                          TrackCount = (int)item.Element("TRACK_COUNT"),
                          Year = (string)item.Element("DATE"),
                          Genre = (string)item.Element("GENRE"),
                          CoverArt = item.Elements("URL").First(u => u.Attribute("TYPE").Value == "COVERART").Value.ToString(),
                          Biography = item.Elements("URL").First(u => u.Attribute("TYPE").Value == "ARTIST_BIOGRAPHY").Value.ToString(),
                          Tracks = item.Elements("TRACK")
                              .Select(t => new Track
                              {
                                  AlbumId = (string)item.Element("GN_ID"),
                                  TrackNumber = (int)t.Element("TRACK_NUM"),
                                  TrackName = (string)t.Element("TITLE"),
                                  TrackId = (string)t.Element("GN_ID"),
                              }).ToList()
                      }).ToList();

    }
    catch (Exception e)
    {
    }

    return albums;
}

这是XML,我正在运行它。在这个例子中,我正在查询的XML中没有传记:

<RESPONSE STATUS="OK">
   <ALBUM>
    <GN_ID>63074689-EDADA0FEDE93683CA03C6D38520A4D88</GN_ID>
    <ARTIST>Green Day</ARTIST>
    <TITLE>American Idiot</TITLE>
    <PKG_LANG>ENG</PKG_LANG>
    <DATE>2004</DATE>
    <GENRE NUM="105222" ID="35474">Punk</GENRE>
    <TRACK_COUNT>13</TRACK_COUNT>
    <TRACK>
      <TRACK_NUM>1</TRACK_NUM>
      <GN_ID>63074690-456E41C113DC8354DC6B25421F2C7989</GN_ID>
      <TITLE>American Idiot</TITLE>
    </TRACK>
    <TRACK>
      <TRACK_NUM>2</TRACK_NUM>
      <GN_ID>63074691-70EFB1E8EB31B5296D5822E55343EFA9</GN_ID>
      <TITLE>Jesus Of Suburbia / City Of The Damned / I Don't Care / Dearly Beloved / Tales Of Another Broken Home</TITLE>
    </TRACK>
    <URL TYPE="COVERART" SIZE="THUMBNAIL" WIDTH="75" HEIGHT="75">http://akamai-b.cdn.cddbp.net/cds/2.0/cover/0A1A/BABF/DEBC/CF21_thumbnail_front.jpg</URL>
    </ALBUM>
  </RESPONSE>
</RESPONSES>

任何人都可以帮我解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

问题是您的XML没有 URL 元素,因此查询失败并抛出InvalidOperationException。将查询中的2个URL行更新为以下内容:

CoverArt = (string)item.Elements("URL").FirstOrDefault(u => u.Attribute("TYPE").Value == "COVERART"),
Biography = (string)item.Elements("URL").FirstOrDefault(u => u.Attribute("TYPE").Value == "ARTIST_BIOGRAPHY"),

查询使用FirstOrDefault,如果找不到结果,则返回null,然后将其强制转换为字符串。或者,您可以在查询前面使用let子句并将其分配给item.Elements("URL"),然后在查询中使用它之前执行三元检查,或者返回null。结果是一样的,但选择的样式取决于你想要做什么,如果它是null并给你一些更大的灵活性。