23

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).

1
  • Thanks for all the responses but not sure why didn't any return any result. I tried all the three solutions and the result was still the same "null". Not sure if I am missing something. Updated code is in my original post. I also tried "spender's" solution but that too returned null. Any idea? Commented May 9, 2011 at 17:07

3 Answers 3

16

You need to include the namespace:

XNamespace ns = "http://tempuri.org/";

xDoc.Descendants(ns + "GetCashFlowReportResponse")
Sign up to request clarification or add additional context in comments.

7 Comments

@user: GetCashFlowReportPdf inherits the namespace. You need to add ns there too.
no, only GetCashFlowReportResponse has the namespace.. other elements doesn't have it.
@user: Wrong. The default namespaces (xmlns="...") is inherited by child elements.
If I add the namespace to GetCashFlowReportPdf then it works but I don't have access to webservice code to change anything. I am just calling the service dynamically and read the HttpWebResponse. What are my other options?
@user: Write c.Element(ns + "GetCashFlowReportPdf")
|
2
XName qualifiedName = XName.Get("GetCashFlowReportResponse", 
    "http://tempuri.org/");

var data = from d in xDoc.Descendants(qualifiedName)

Comments

2

Just ask for the elements using the qualified names:

// create a XML namespace object
XNamespace ns = XNamespace.Get("http://tempuri.org/");

var data = from c in xDoc.Descendants(ns + "GetCashFlowReportResponse")
           select (string)c.Element(ns + "GetCashFlowReportPdf");

Note the use of the overloaded + operator that creates a QName with a XML namespace and a local name string.

2 Comments

What difference it makes to have code like XNamespace ns = "tempuri.org"; and adding XNamespace.Get()?
My answer uses an implicit cast; they're equivalent.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.