Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XDocument and Linq returns null if the element has xmlns attribute

Tags:

Newbie with XDocuments and Linq, please suggest a solution to retrieve the data from a particular tag in the xml string:

If I have a XML string from webservice response (I formatted xml for ease):

<?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">   <soap:Body>     <GetCashFlowReportResponse xmlns="http://tempuri.org/">       <GetCashFlowReportPdf>Hello!</GetCashFlowReportPdf>     </GetCashFlowReportResponse>   </soap:Body> </soap:Envelope> 

Using the following code, I can get the value only if GetCashFlowReportResponse tag doesn't have "xmlns" attribute. Not sure why? Otherwise, it always return null.

string inputString = "<?xml version=\"1.0\" encoding=\"utf-8\"?><soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><soap:Body><GetCashFlowReportResponse xmlns=\"http://tempuri.org/\"><GetCashFlowReportPdf>Hello!</GetCashFlowReportPdf></GetCashFlowReportResponse></soap:Body></soap:Envelope>"     XDocument xDoc = XDocument.Parse(inputString); //XNamespace ns = "http://tempuri.org/"; XNamespace ns = XNamespace.Get("http://tempuri.org/");  var data = from c in xDoc.Descendants(ns + "GetCashFlowReportResponse")            select (string)c.Element("GetCashFlowReportPdf");  foreach (string val in data) {     Console.WriteLine(val); } 

I can't change the web service to remove that attribute. IS there a better way to read the response and get the actual data back to the user (in more readable form)?

Edited: SOLUTION:

XDocument xDoc = XDocument.Parse(inputString); XNamespace ns = "http://tempuri.org/";  var data = from c in xDoc.Descendants(ns + "GetCashFlowReportResponse")            select (string)c.Element(ns + "GetCashFlowReportPdf"); foreach (string val in data) {    Console.WriteLine(val); } 

Note: Even if all the child elements doesn't have the namespace attribute, the code will work if you add the "ns" to the element as I guess childs inherit the namespace from parent (see response from SLaks).

like image 277
Sri Reddy Avatar asked May 09 '11 16:05

Sri Reddy


1 Answers

You need to include the namespace:

XNamespace ns = "http://tempuri.org/";  xDoc.Descendants(ns + "GetCashFlowReportResponse") 
like image 161
SLaks Avatar answered Oct 05 '22 07:10

SLaks