LINQ to XML get elements from XML data

Hi I have a web service call returning an XML string.  I would like to load this into a listbox (Windows Phone 7) but I am having trouble getting the data out.  I can see the data in the string returned from the web service.  I can also see the XML document parse it right but I cannot get a collection of items with the LINQ I am using

This line works fine (I tried different LoadOtions but it doesn't make any difference)
                XDocument xDoc = XDocument.Parse(e.Result, LoadOptions.None);

accounts is NULL after the select is executed.  The foreach was a desperate test but it doesn't get anywhere


void client_GetAccountsForUserCompleted(object sender, mobileSvc.GetAccountsForUserCompletedEventArgs e)
        {
            try
            {
                //MessageBox.Show(e.Result);

                XDocument xDoc = XDocument.Parse(e.Result, LoadOptions.None);

                var accounts = from accountElem in xDoc.Descendants("Account")
                           select new Account
                           {
                               AccountNumber = accountElem.Attribute("AccountNumber").Value,
                               CompanyName = accountElem.Attribute("CampanyName").Value,
                           };

                foreach (var item in accounts)
                {
                     MessageBox.Show(item.CompanyName);
                }
                this.lstAccounts.ItemsSource = accounts;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

Open in new window

LVL 12
gbzhhuAsked:
Who is Participating?
 
Fernando SotoRetiredCommented:
The use of GetDefaultNamespace will work better then hard coding it in just in case they change it the program will not crash because of it.

// As used in my code snippet above.
XNamespace ns = xDoc.Root.GetDefaultNamespace( );
0
 
wdosanjosCommented:
Please post a sample XML.
0
 
gbzhhuAuthor Commented:
Sorry was meaning to
<?xml version="1.0" encoding="utf-8" ?> 
  <string xmlns="http://test.co.uk/"><Accounts><Account AccountId="1" AccountNumber="0110100" CompanyName="Abbey Green Vets Ltd" Add2="The Veterinary Surgery" Add4="Church Close" City="Broadway" County="Worcestershire" PostCode="WR12 7AH"><Locations><Location LocationId="3548" LocationName="Mobile -Abbey Green" Default="0" /><Location LocationId="3931" LocationName="Mobile - Adrian to remove" Default="0" /></Locations></Account><Account AccountId="68" AccountNumber="0110200" CompanyName="Arthur Lodge Veterinary Hospital" Add4="17 Brighton Road" City="Horsham" County="West Sussex" PostCode="RH13 5BD"><Locations><Location LocationId="3742" LocationName="Adrian - AL3" Default="0" /><Location LocationId="3834" LocationName="Adrian AL4" Default="0" /></Locations></Account><Account AccountId="135" AccountNumber="0110300" CompanyName="Vets West Harleigh Vets Ltd" Add2="The Veterinary Surgery" Add4="Harleigh Road" City="Bodmin" County="Cornwall" PostCode="PL31 1AQ" /><Account AccountId="336" AccountNumber="0110800" CompanyName="Arun Veterinary Group" Add2="The Veterinary Surgery" Add4="121 Lower Street" City="Pulborough, West Sussex" County="West Sussex" PostCode="RH20 2BP" /><Account AccountId="805" AccountNumber="0111700" CompanyName="Abivale Vet Group Ltd - Didcot" Add2="Hadden Farm Veterinary Centre" Add4="Wallingford Road" City="Didcot" County="Oxfordshire" PostCode="OX11 9BJ" /><Account AccountId="872" AccountNumber="0111800" CompanyName="Archway Veterinary Surgery" Add3="21 High Street" Add4="Highworth" City="Swindon, Wiltshire" County="Wiltshire" PostCode="SN6 7AG" /></Accounts></string>

Open in new window

0
Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
oxyooCommented:
the xmlns attribute in the string element is causing the problem, if you remove it, it will work just fine.
0
 
oxyooCommented:
Oh, there is also a spelling error in the c# code "CampanyName" -> "CompanyName"
0
 
wdosanjosCommented:
You are missing the namespace, which I included below.  BTW, the CompanyName string was mispelled as CampanyName, which was causing a NullReferenceException.

void client_GetAccountsForUserCompleted(object sender, mobileSvc.GetAccountsForUserCompletedEventArgs e)
        {
            try
            {
                //MessageBox.Show(e.Result);

                XDocument xDoc = XDocument.Parse(e.Result, LoadOptions.None);
                XNamespace ns = "http://test.co.uk/";

                var accounts = from accountElem in xDoc.Descendants(ns + "Account")
                           select new Account
                           {
                               AccountNumber = accountElem.Attribute("AccountNumber").Value,
                               CompanyName = accountElem.Attribute("CompanyName").Value,
                           };

                foreach (var item in accounts)
                {
                     MessageBox.Show(item.CompanyName);
                }
                this.lstAccounts.ItemsSource = accounts;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

Open in new window

0
 
dimajCommented:
I've written a small blog article on using Linq to parse XML. See if this works for you... http://blog.dimaj.net/2011/02/howto-update-xml-file-using-linq/
0
 
Fernando SotoRetiredCommented:
Hi gbzhhu;

You need to add a namespase to access the nodes because one is defined in the root node. You also had a typeO in the foreach loop, you had CampanyName where it should have been CompanyName. I also added some error checking in as well.

XDocument xDoc = XDocument.Parse( xml );
if (xDoc.Root != null)
{
    XNamespace ns = xDoc.Root.GetDefaultNamespace( );

    var accounts = from accountElem in xDoc.Descendants( ns + "Account" )
                   select new Account
                   {
                       AccountNumber = (accountElem.Attribute( "AccountNumber")  != null) ? accountElem.Attribute( "AccountNumber").Value : "No Account Number",
                       CompanyName = (accountElem.Attribute( "CompanyName") != null) ? accountElem.Attribute( "CompanyName" ).Value : "No Company Name"
                   };

    foreach (var item in accounts)              
    {                                           
         MessageBox.Show(item.CompanyName);     
    }                                           
    this.lstAccounts.ItemsSource = accounts;    
}

Open in new window


Fernando
0
 
gbzhhuAuthor Commented:
Wow, what a wonderful response.  Thank you all.  I used Fenando's default namespace and it works just fine.

wdosanjos thanks for contributing but oxyoo got the answer in before you.

Dimaj thank for sharing your blog.

0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.