Iterate through nested XML nodes and save it to a list in asp.net c#
I have a xml file with nested xml nodes. i need to loop through the nodes and save the innertext to list. The xml format is like below:
<xml> <record> </record> <Actions> <Action Name= "name1"> <screen> <subAction></SubAction> </screen> </Action> <Action Name = "name2"> <screen Description= "info"> <subAction> <object> <name> user </name> <type> string </type> <variable> ram </variable> </object> <object> <name> user1 </name> <type> string1 </type> <variable> ram1 </variable> </object> </subAction> </screen> <Screen Description= "info1"> <subAction> <object> </object> </subAction> </Screen>....goes on </Action> </Actions> </xml>
I need to check if Action == name2, loop through and get all the object types in list. I am not able to get nested nodes.
Below is the code i have tried:
XmlNodeList NodesPro = xmlDoc.SelectNodes("/xml/Actions/Action"); foreach (XmlNode pronode in NodesPro) { bool flag = false; if (pronode.Attributes["Name"].Value == "name2") { //Dont know how to proceed. Please help }
I prefer @Yitzhak solution, but if you want to use XmlDocument
, you could try the following :
1 – Create class ActionObject
:
public class ActionObject { public string Name { get; set; } public string Type { get; set; } public string Variable { get; set; } }
2 – Xml
string xml2 = @" <xml> <record> </record> <Actions> <Action Name= 'name1'> <screen></screen> <subAction></subAction> </Action> <Action Name = 'name2'> <screen Description= 'info'> <subAction> <object> <name> user </name> <type> string </type> <variable> ram </variable> </object> <object> <name> user1 </name> <type> string1 </type> <variable> ram1 </variable> </object> </subAction> </screen> <Screen Description= 'info1'> <subAction> <object></object> </subAction> </Screen> </Action> </Actions> </xml>";
3 – Code that get objects from xml:
XmlDocument xmlDocument = new XmlDocument(); xmlDocument.LoadXml(xml2); List<ActionObject> objects = new List<ActionObject>(); XmlNodeList actions = xmlDocument.DocumentElement.SelectNodes("/xml/Actions/Action"); foreach (XmlElement actionNode in actions) { if (actionNode.Attributes["Name"].Value != "name2") continue; foreach(XmlNode objectNode in actionNode.SelectNodes("./screen/subAction/object")) { ActionObject actionObject = new ActionObject { Name = objectNode.SelectSingleNode("name").InnerText.Trim(), Type = objectNode.SelectSingleNode("type").InnerText.Trim(), Variable = objectNode.SelectSingleNode("variable").InnerText.Trim(), }; objects.Add(actionObject); } }
I hope you find this helpful.
It is better to use LINQ to XML API. It is available in the .Net Framework for more than a decade.
The XML provided is not well-formed. I had to fix it.
It is not clear what is your desired output.
I copied @Sajid’s class as a placeholder for data.
c#
void Main() { XDocument xsdoc = XDocument.Parse(@"<xml> <record> </record> <Actions> <Action Name='name1'> <screen> <subAction></subAction> </screen> </Action> <Action Name='name2'> <screen Description='info'> <subAction> <object> <name>user</name> <type>string</type> <variable>ram</variable> </object> <object> <name>user1</name> <type>string1</type> <variable>ram1</variable> </object> </subAction> </screen> <Screen Description='info1'> <subAction> <object> </object> </subAction> </Screen>....goes on</Action> </Actions> </xml>"); List<ActionObject> objects3 = new List<ActionObject>(); foreach (var el in xsdoc.Descendants("Action") .Where(x => x.Attribute("Name").Value.Equals("name2"))) { objects3 = el.Descendants("object") .Select(p => new ActionObject() { Name = p.Element("name")?.Value, Type = p.Element("type")?.Value, Variable = p.Element("variable")?.Value }).ToList(); } } public class ActionObject { public string Name { get; set; } public string Type { get; set; } public string Variable { get; set; } }