Search code examples
c#xmlweb-serviceslinq-to-xmlxmlreader

Reading XML nodes from web service


I have been playing around with a simple application for Windows Phone 7 using web services over http with XML responses. I'm using the following API http://api.chartlyrics.com/apiv1.asmx/

My issues are with reading the returned XML.

The function SearchLyricDirect e.g. http://api.chartlyrics.com/apiv1.asmx/SearchLyricDirect?artist=michael%20jackson&song=bad return the following xml:

   <GetLyricResult xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://api.chartlyrics.com/">
          <TrackId>0</TrackId>
          <LyricChecksum>8a84ddec06f4fffe067edd2fdbece21b</LyricChecksum>
          <LyricId>1710</LyricId>
          <LyricSong>Bad</LyricSong>
          <LyricArtist>Michael Jackson</LyricArtist>
          <LyricUrl>
                 http://www.chartlyrics.com/28h-8gWvNk-Rbj1X-R7PXg/Bad.aspx
          </LyricUrl>
          <LyricCovertArtUrl>
                 http://ec1.images-amazon.com/images/P/B000CNET66.02.MZZZZZZZ.jpg
          </LyricCovertArtUrl>
          <LyricRank>9</LyricRank>
          <LyricCorrectUrl>
                 http://www.chartlyrics.com/app/correct.aspx?lid=MQA3ADEAMAA=
          </LyricCorrectUrl>
          <Lyric>
                    .......Lyric.......
          </Lyric>
   </GetLyricResult>

I have tried using a XmlReader but it says there are illegal characters e.g. XmlReader xmlr = XmlReader.Create(e.Result);

I've tried using XDocument instead, but I cannot get any values out for elements under "GetLyricResult".

  XDocument xmltest = XDocument.Parse(e.Result);
  Console.WriteLine(xmltest.Element("Lyric").Value);

I'm sure it is very simple.

Thank you!


Solution

  • You're not paying attention to the XML namespace that's defined!

    <GetLyricResult xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
                    xmlns="http://api.chartlyrics.com/">
    

    What you need to do is define that XML namespace in your Linq-to-XML query, too:

     XDocument xmltest = XDocument.Parse(e.Result);
     XNamespace ns = "http://api.chartlyrics.com/";
    
     Console.WriteLine(xmltest.Element(ns + "GetLyricResult").Element(ns + "Lyric").Value);
    

    Also: your code wasn't gonna work anyway - if you use .Element, you need to reference all elements from the root on - so here you first need to "resolve" the <GetLyricResult> root node, and only after that, you can reach in and grab the <Lyric> node