简体   繁体   中英

How to use “let” to deal with missing XML nodes?

I'm updating my question here based on some feedback I got in response to my original post. I'm trying to parse some xml in an XDocument and not getting the results that I expect. Based on feedback below I've added the two let statements below, but they're not working as expected and I assume that I've got them wrong somehow. The problem is that when the CoverArt and Biography are not present in the XML result I get nothing back from my query Here is the code that I am running:

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

Here is the XML, I'm running it against. In this example there is no Biography in the XML that I'm querying:

<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>

Can anyone help me out with this?

The problem is your XML has no URL elements, so the query is failing and throws an InvalidOperationException . Update the 2 URL lines in your query to the following:

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"),

The query uses FirstOrDefault and will return null if the result isn't found, then casts it to a string. Alternately, you could use a let clause earlier in the query and assign it to item.Elements("URL") then do a ternary check before using it in the query, or return null. The result is the same, but the style chosen depends on what you want to do if it's null and gives you some more flexibility.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM