user2727195
user2727195

Reputation: 7330

xml parsing of a soap envelope using XmlDocument

I'm starting out parsing XML in C# using XmlDocument. I've following xml

<?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>
        <ns1:getCustomersResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://DefaultNamespace">
            <getCustomersReturn soapenc:arrayType="soapenc:string[2]" xsi:type="soapenc:Array" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
                <getCustomersReturn xsi:type="soapenc:string"></getCustomersReturn>
                <getCustomersReturn xsi:type="soapenc:string">some data</getCustomersReturn>
                <getCustomersReturn xsi:type="soapenc:string">some more data</getCustomersReturn>
            </getCustomersReturn>
        </ns1:getCustomersResponse>
    </soapenv:Body>
</soapenv:Envelope>

My Code:

XmlDocument xmlDocument = new XmlDocument();
xmlDocument.LoadXml(result);  //loading soap message as string
XmlNamespaceManager xmlNamespaceManager = new XmlNamespaceManager(xmlDocument.NameTable);

xmlNamespaceManager.AddNamespace("ns1", "http://DefaultNamespace"); 

XmlNodeList xmlNodeList = xmlDocument.SelectNodes("//ns1:getCustomersResponse/getCustomersReturn", xmlNamespaceManager);

string[] results = new string[xmlNodeList.Count];

var str = "";
var count = 0;
foreach (XmlNode xmlNode in xmlNodeList)
{
    str += xmlNode.InnerText;
}

Assert.IsNull(results, xmlNodeList.Count + ", " + count + ", " + str);

I want to retrieve the child nodes (text) of getCustomersReturn as a string[]

Problem:

All the nodes are getting flattened into a single string instead of an array.

xmlNodeList.Count is coming as 1 instead of 3

Edit: subsequent problems after implementing the answers

CS1061  'XmlDocument' does not contain a definition for 'SelectNodes' and no extension method 'SelectNodes' accepting a first argument of type 'XmlDocument' could be found (are you missing a using directive or an assembly reference?)

Upvotes: 0

Views: 5003

Answers (2)

Johan Shen
Johan Shen

Reputation: 168

Just using a XPath expression, this code is simple but can help you know what problem do you have. This link can help you understand XPath : https://en.wikipedia.org/wiki/XPath

    var xml = new XmlDocument();
    xml.LoadXml(xmlstring);
    XmlNamespaceManager manager = new XmlNamespaceManager(xml.NameTable);
    manager.AddNamespace("ns1", "http://DefaultNamespace");
    //select all nodes using XPath
    var search = xml.SelectNodes("//ns1:getCustomersResponse/getCustomersReturn//getCustomersReturn",manager);
    //saving XmlNodeList to List<string>
    var r = new List<string>();
    foreach (XmlNode item in search)
        r.Add(item.InnerText);
    string[] ary = r.ToArray(); //convert List<string> to string[]

Upvotes: 0

Chintan Udeshi
Chintan Udeshi

Reputation: 362

There is one change in your code. Replace the line :

XmlNodeList xmlNodeList = xmlDocument.SelectNodes("//ns1:getCustomersResponse/getCustomersReturn", xmlNamespaceManager);

with the below line

XmlNodeList xmlNodeList = xmlDocument.SelectNodes("//ns1:getCustomersResponse/getCustomersReturn/getCustomersReturn", xmlNamespaceManager);

Use the below code it will give you the desired output

    XmlDocument xmlDocument = new XmlDocument();
                xmlDocument.LoadXml(result);  //loading soap message as string
                XmlNamespaceManager xmlNamespaceManager = new XmlNamespaceManager(xmlDocument.NameTable);

                xmlNamespaceManager.AddNamespace("ns1", "http://DefaultNamespace");

                XmlNodeList xmlNodeList = xmlDocument.SelectNodes("//ns1:getCustomersResponse/getCustomersReturn/getCustomersReturn", xmlNamespaceManager);

                string[] results = new string[xmlNodeList.Count];

                var str = "";
                var count = 0;
                foreach (XmlNode xmlNode in xmlNodeList)
                {
                    str += xmlNode.InnerText;
                }

                Assert.IsNull(results, xmlNodeList.Count + ", " + count + ", " + str);

Upvotes: 2

Related Questions