Reading multiple child nodes of xml file
You could use an XPath approach like so:
XmlNodeList xnl = doc.SelectNodes(string.Format("/Periods/PeriodGroup[@name='{0}']/Period", PG));
Though prefer LINQ to XML for it's readability.
This will return Period
node children based on the PeriodGroup
name
attribute supplied, e.g. HER
:
XDocument xml = XDocument.Load(HttpContext.Current.Server.MapPath(FileLoc));var nodes = (from n in xml.Descendants("Periods") where n.Element("PeriodGroup").Attribute("name").Value == "HER" select n.Element("PeriodGroup").Descendants().Elements()).ToList();
Results:
<PeriodName>Prehistoric</PeriodName><StartDate>-500000</StartDate><EndDate>43</EndDate><PeriodName>Iron Age</PeriodName><StartDate>-800</StartDate><EndDate>43</EndDate><PeriodName>Roman</PeriodName><StartDate>43</StartDate><EndDate>410</EndDate>
The query is pretty straightforward
from n in xml.Descendants("Periods")
Will return a collection of the descendant elements for the element Periods
.We then use where
to filter this collection of nodes based on attribute value:
where n.Element("PeriodGroup").Attribute("name").Value == "HER"
Will then filter down the collection to PeriodGroup
elements that have a name
attribute with a value of HER
Finally, we select the PeriodGroup
element and get it's descendant nodes
select n.Element("PeriodGroup").Descendants().Elements()
EDIT (See comments)
Since the result of this expression is just a query, we use .ToList()
to enumerate the collection and return an object containing the values you need. You could also create anonymous types to store the element values for example:
var nodes = (from n in xml.Descendants("Period"). Where(r => r.Parent.Attribute("name").Value == "HER") select new { PeriodName = (string)n.Element("PeriodName").Value, StartDate = (string)n.Element("StartDate").Value, EndDate = (string)n.Element("EndDate").Value }).ToList();//Crude demonstration of how you can reference each specific element in the result//I would recommend using a stringbuilder here..foreach (var n in nodes){ text += "<br>" + n.PeriodName; text += "<br>" + n.StartDate; text += "<br>" + n.EndDate;}
This is what the nodes
object will look like after the query has run:
Since the XmlDocument.SelectNodes
method actually accepts an XPath expression, you're free to go like this:
XmlNodeList xnl = doc.SelectNodes("/Periods/PeriodGroup[@name='" + PG + "']/Period");foreach (XmlNode node in xnl) { // Every node here is a <Period> child of the relevant <PeriodGroup>.}
You can learn more on XPath at w3schools.
go thru this
public static void XMLNodeCheck(XmlNode xmlNode) { if (xmlNode.HasChildNodes) { foreach (XmlNode node in xmlNode) { if (node.HasChildNodes) { Console.WriteLine(node.Name); if (node.Attributes.Count!=0) { foreach (XmlAttribute att in node.Attributes) { Console.WriteLine("----------" + att.Name + "----------" + att.Value); } } XMLNodeCheck(node);//recursive function } else { if (!node.Equals(XmlNodeType.Element)) { Console.WriteLine(node.InnerText); } } } } }