Parsing a SOAP response with LINQ to XML - how to get nested nodes under the parent?

I have a SOAP answer that looks something like this:

<?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Body> <getLoginResponse xmlns="http://<remotesite>/webservices"> <person_id>123456</person_id> <person_name>John Doe</person_name> </getLoginResponse> </soapenv:Body> </soapenv:Envelope> 

I was able to successfully retrieve the <get LoginResponse ...> node with the following LINQ code:

 string soapResult = rd.ReadToEnd(); XNamespace ns = "http://<remotesite>/webservices"; XDocument xDoc = XDocument.Parse(soapResult); var respUser = (from r in xDoc.Descendants(ns + "getLoginResponse") select new User { Name = r.Element("person_name").Value }).FirstOrDefault(); 

However, calling Name = r.Element("person_name").Value gives me an error Object reference not set to an instance of an object .

I examined this further, and I see that if I run this query, all values ​​(person_id, person_name) are actually in the nested collection .Descendants().Descendants() XElement:

 var respUser = (from r in xDoc.Descendants(ns + "getLoginResponse") select r).Descendants().ToList(); 

So, what tells me in my original LINQ query, I am not correctly <getLoginResponse> nodes in <getLoginResponse> .

How to combine this together using ... select new User { ... } to populate my user object?

Doing something like:

 var respUser = (from r in xDoc.Descendants(ns + "getLoginResponse").Descendants() select new User() { Name = r.Element("person_name").Value }).FirstOrDefault(); 

Doesn't work very well :)

Thanks to everyone for the solution - I missed the namespace from the children, which caused my problem!

+7
source share
2 answers

You need to add a valid namespace to your request, in your example it will be "http://foobar/webservices" , for example:

 XElement xml = XElement.Load(@"testData.xml"); XNamespace foobar = "http://foobar/webservices"; string personId = xml.Descendants(foobar + "person_id").First().Value; 
+6
source

You need to include the namespace:

 r.Element(ns + "person_name").Value 
+2
source

All Articles