Reputation: 7330
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
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
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