REST with LINQ to XML

With LINQ to XML, what I have learned so far, it's awesome, it is not only the first class concept of processing XML data, but also let you process a complex XML doc in the most simplest and readable way.

I have a project called, Linq.Flickr , and I often need to process  XML data for REST query.

To show a simple example of LINQ to XML, lets take a REST response from a Flickr method called flickr.people.getUploadStatus and see how it is processed.

<user id="12037949754@N01" ispro="1">  
<username>Bees</username> 
<bandwidth maxbytes="2147483648" maxkb="2097152" 
usedbytes="383724" usedkb="374" remainingbytes="2147099924" remainingkb="2096777" /> 
<filesize maxbytes="10485760" maxkb="10240" /> 
<sets created="27" remaining="lots" /> 
</user>

Before .net 3.5. it could have been done by GetElementyByTagName("users") - > inside the while loop getting the element, reading value, storing it in private variables , going to next sibling and repeat, if nested , then take the first child and so forth. But , in .net 3.5 using LINQ , the translation is not only just like XML itself, moreover , in XElement.Load , we can directly pass the REST query string.

So, Two, steps to do a REST with LINQ

  1. Build the URL and pass it to XElement.Load
  2. Parse the response and take necessary actions.

For example, for the above XML, I wrote something like below, in PhotoRepository.cs, that does a selective parsing.

try
{  
    XElement element = GetElement(##REQUEST URL##);

    People people = (from p in element.Descendants("user")
      select new People
      {
            Id = p.Attribute("id").Value ?? string.Empty,
            IsPro =
            Convert.ToInt32(p.Attribute("ispro").Value) == 0 ? false : true,
            BandWidth =
            (from b in element.Descendants("bandwidth")
               select new BandWidth
                {
                      RemainingKB = 
                      Convert.ToInt32(b.Attribute("remainingkb").Value),
                      UsedKB = Convert.ToInt32(b.Attribute("usedkb").Value)
                 }).Single<BandWidth>()
               }).Single<People>();

    return people;
}
catch (Exception ex)
{
    throw new ApplicationException("Could not process response", ex);
}

Note :GetElement is a local method that does a XElement.Load, with some validation check.

Here my Client-Side object looks like

People
Id
IsPro
BandWidth
   RemainingKB
   UsedKB

The most interesting thing is, everything is done on the fly , no loop, no intermediate result tracking, no headache of sibling and first child.Overall, the code has a high point in terms of readability.

Take that !!

kick it on DotNetKicks.com

6 Comments

  • Good Linq code example. Thanks

  • Excellent, I wasn't aware you could use a rest URL with GetElement. This will make parsing XML much easier. Thanks!

  • Michael and Denny thanks a lot for your comments, it is my pleasure that you liked it.

  • Thanks, kazi, noted!

  • Hi
    I am very new to linq.
    I have xml structure like below
    &lt;Page Name="Page1"&gt;
    &nbsp;&lt;Controls&gt;
    &nbsp;&lt;control&gt;
    &nbsp;&lt;TextBox1 ID="TextBox1" ControlType="System.Web.UI.WebControls.TextBox" ControlData="rajesh" /&gt;
    &lt;/control&gt;
    &nbsp;&lt;control&gt;
    &nbsp;&lt;TextBox2 ID="TextBox2" ControlType="System.Web.UI.WebControls.TextBox" ControlData="ajay" /&gt;
    &lt;/control&gt;
    &nbsp;&lt;control&gt;
    &nbsp;&lt;TextBox3 ID="TextBox3" ControlType="System.Web.UI.WebControls.TextBox" ControlData="poonam" /&gt;
    &nbsp;&lt;/control&gt;
    &nbsp;&lt;control&gt;
    &nbsp;&lt;TextBox4 ID="TextBox4" ControlType="System.Web.UI.WebControls.TextBox" ControlData="manoj" /&gt;
    &nbsp;&lt;/control&gt;
    &nbsp;&lt;control&gt;
    &nbsp;&lt;txtpntest1 ID="txtpntest1" ControlType="System.Web.UI.WebControls.TextBox" ControlData="" /&gt;
    &nbsp;&lt;/control&gt;
    &nbsp;&lt;control&gt;
    &nbsp;&lt;txtpntest2 ID="txtpntest2" ControlType="System.Web.UI.WebControls.TextBox" ControlData="" /&gt;
    &nbsp;&lt;/control&gt;
    &nbsp;&lt;control&gt;
    &nbsp;&lt;txtpntest3 ID="txtpntest3" ControlType="System.Web.UI.WebControls.TextBox" ControlData="" /&gt;
    &nbsp;&lt;/control&gt;
    &nbsp;&lt;control&gt;
    &nbsp;&lt;pnltest ID="pnltest" ControlType="System.Web.UI.WebControls.Panel" /&gt;
    &nbsp;&lt;/control&gt; &nbsp;
    &nbsp;&lt;/Controls&gt;
    &lt;DocCollection&gt;
    &lt;DocName&gt;
    Purchase order
    &lt;/DocName&gt;
    &lt;DocDescription&gt;
    to raise a purchase order
    &lt;/DocDescription&gt;
    &lt;/DocCollection&gt;
    &lt;/Page&gt;
    i have business entity class which has three property
    1&gt;Controlcollection of type string
    2&gt;DocDescription of type string
    3&gt;DocName of type string
    what i want is to fill Controlcollection &nbsp;with the data in control collection within Controls node and DocDescription &nbsp;with DocDescription within DocCollection node and DocName with DocName within DocCollection &nbsp;node
    Please help to resolve above issuse
    Thanks

  • Hi Rajesh,
    As i have showed in my post that if you want to find nodes under a certain node ,

    you can do like

    var query = from control in doc.Decendants("control")
    select new SomeClass
    {
    SomeProperty = control.Element("Textbox1").Attribute("ID").Value ?? string.Empty.
    }

    This is the simplest form to start with, you can furter do it dynamic by getting all the textbox Element and running a query for each.

    Hope this helps,

Comments have been disabled for this content.