0

I'm trying to create a C# application that extracts data from pages like this one. It's basically an XML file that stores information about a music album. Here's the relevant code:

<resp stat="ok" version="2.0">
  <release id="368116" status="Accepted">
  <title>The Bends</title>
    <tracklist>
      <track>
        <position>1</position>
        <title>Planet Telex</title>
        <duration>4:18</duration>
      </track>
   </tracklist>
 </release>

I'd like to extract all the track titles from the album (in the above code "Planet Telex") and output them in a list like this:

Planet Telex
The Bends
...

what would be the best/most elegant way to do this? From what I've read, the XmlTextReader is a good class to use. I've also seen many mentions of Linq to XML... Thanks in advance!

BTW, I've posted this question again (albeit formulated differently). I'm not sure why it was removed last time.

Daan
  • 1,417
  • 5
  • 25
  • 40
  • 1
    Probably because it's a duplicate of duplicates of duplicates: http://stackoverflow.com/questions/1238528/parse-xml-document-in-c-sharp, http://stackoverflow.com/questions/2635618/parse-xml-from-string, http://stackoverflow.com/questions/55828/best-practices-to-parse-xml-files, http://stackoverflow.com/questions/8194155/c-sharp-parse-xml-file – Michael Sondergaard Jan 24 '12 at 15:36

4 Answers4

3

If you can, go with LINQ to XML:

XDocument doc = XDocument.Load(xml);
var titles = doc.Descendants("title").Select(x => x.Value);

A more sophisticated version that distinguishes between the album and the track title is the following:

var titles = doc.Descendants("release")
                .Select(x => new
                             {
                                 AlbumTitle = x.Element("title").Value,
                                 Tracks = x.Element("tracklist")
                                           .Descendants("title")
                                           .Select(y => y.Value)
                             });

It returns a list of anonymous types, each with a property AlbumTitle of type string and an IEnumerable<string> representing the track titles.

Daniel Hilgarth
  • 171,043
  • 40
  • 335
  • 443
  • Thanks! I just noticed that I forgot a crucial bit of info. I added it to the above code. – Daan Jan 24 '12 at 15:37
  • And what is that new title tag? The album title? – Daniel Hilgarth Jan 24 '12 at 15:38
  • @KeyMs92: Well, it will still work this way. It will output the album title first and then the track titles. – Daniel Hilgarth Jan 24 '12 at 15:41
  • Ok, so you mean that I just skip the first element of the array to get all the track titles? Would there be an easy way to e.g. list all the title elements within the tracklist element? – Daan Jan 24 '12 at 15:45
  • @KeyMs92: Please see update for a more sophisticated version. – Daniel Hilgarth Jan 24 '12 at 15:46
  • Right... Do you think it would matter anything to use the first method and skip the first element of the array vs. the second method? – Daan Jan 24 '12 at 15:50
  • It does matter in several aspects: (1) Performance: The first code needs to traverse the XML tree only once. The second code traverses it once + N times partly, once for each album in the XML file. (2) Readability: If you want to get the title of the album and the track titles separately, the second code is very much easier to read. Using the first one and skipping the first result is not self documenting. You need to explain to later readers of your code, why you are skipping the first item. – Daniel Hilgarth Jan 24 '12 at 15:54
  • Conclusion: Use the second code. Only think about using the first code with the skipping if you really have a performance problem. Not if you think you might have one in the future, but if you **really** have one. – Daniel Hilgarth Jan 24 '12 at 15:56
0

Use xsd.exe to generate a class structure from your XML file, then deserialize your XML into that class structure. It should be pretty straightforward.

Daniel Mann
  • 57,011
  • 13
  • 100
  • 120
0

Check out this simpleXml library

https://bitbucket.org/kberridge/simplexml

It's on NuGet by the way!

Install-package simpleXml

Bassam Mehanni
  • 14,796
  • 2
  • 33
  • 41
0

Although LINQ is certainly a valid approach, I figured I would mention at least one quick alternative: XPath. Here is an example:

XPathDocument doc = new XPathDocument("http://api.discogs.com/release/368116?f=xml");
XPathNavigator nav = doc.CreateNavigator();
XPathNodeIterator iter = (XPathNodeIterator)nav.Evaluate("//tracklist/track/title");

while (iter.MoveNext())
{
    Console.WriteLine(iter.Current.Value);
}

Output is as follows:

Planet Telex
The Bends
High And Dry
Fake Plastic Trees
Bones
(Nice Dream)
Just
My Iron Lung
Bullet Proof..I Wish I Was
Black Star
Sulk
Street Spirit (Fade Out)

Note that I added ?f=xml on your sample URL, since the default output from the API is JSON.

remarkrm
  • 159
  • 2