读取xml文件的多个子节点

我创建了一个带有示例内容的Xml文件,如下所示:

    Prehistoric -500000 43   Iron Age -800 43   Roman 43 410     Prehistoric -500000 43   Roman 43 410   Anglo-Saxon 410 800    

我需要能够读取所选PeriodGroup中的Period节点子节点。 我想PeriodName可能是Period的一个属性,如果这更合理的话。

我看了很多例子,但似乎都不是很正确,似乎有很多不同的方法,有些使用XmlReader,有些是XmlTextReader,有些则没有使用。 由于这是我第一次阅读Xml文件,我想我会问是否有人可以给我一个指针。 我有一些工作只是为了尝试,但它感觉笨重。 我正在使用VS2010和c#。 另外,我看到很多人都在使用LINQ-Xml,所以我很欣赏使用这种方法的优点和缺点。

 string PG = "HER"; XmlDocument doc = new XmlDocument(); doc.Load(Server.MapPath("./Xml/XmlFile.xml")); string text = string.Empty; XmlNodeList xnl = doc.SelectNodes("/Periods/PeriodGroup"); foreach (XmlNode node in xnl) { text = node.Attributes["name"].InnerText; if (text == PG) { XmlNodeList xnl2 = doc.SelectNodes("/Periods/PeriodGroup/Period"); foreach (XmlNode node2 in xnl2) { text = text + "
" + node2["PeriodName"].InnerText; text = text + "
" + node2["StartDate"].InnerText; text = text + "
" + node2["EndDate"].InnerText; } } Response.Write(text); }

你可以像这样使用XPath方法:

 XmlNodeList xnl = doc.SelectNodes(string.Format("/Periods/PeriodGroup[@name='{0}']/Period", PG)); 

虽然它更喜欢LINQ to XML,但它的可读性。

这将根据提供的PeriodGroup name属性返回Period节点子节点,例如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(); 

结果:

 Prehistoric -500000 43 Iron Age -800 43 Roman 43 410 

查询非常简单

 from n in xml.Descendants("Periods") 

将返回元素Periods的后代元素的集合。 然后我们使用where根据属性值过滤这个节点集合:

 where n.Element("PeriodGroup").Attribute("name").Value == "HER" 

然后将集合过滤到具有值为HERname属性的PeriodGroup元素

最后,我们选择PeriodGroup元素并获取它的后代节点

 select n.Element("PeriodGroup").Descendants().Elements() 

编辑(见评论)

由于此表达式的结果只是一个查询,我们使用.ToList()来枚举集合并返回包含所需值的对象。 您还可以创建匿名类型来存储元素值,例如:

 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 += "
" + n.PeriodName; text += "
" + n.StartDate; text += "
" + n.EndDate; }

这是查询运行后nodes对象的样子:

在此处输入图像描述

由于XmlDocument.SelectNodes方法实际上接受了XPath表达式,因此您可以像这样自由:

 XmlNodeList xnl = doc.SelectNodes("/Periods/PeriodGroup[@name='" + PG + "']/Period"); foreach (XmlNode node in xnl) { // Every node here is a  child of the relevant . } 

您可以在w3schools上了解有关XPath的更多信息。

通过这个

  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); } } } } }