读取xml文件的多个子节点 [英] Reading multiple child nodes of xml file

查看:88
本文介绍了读取xml文件的多个子节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have created an Xml file with example contents as follows:

<?xml version="1.0" encoding="utf-8" ?>
<Periods>
  <PeriodGroup name="HER">
    <Period>
      <PeriodName>Prehistoric</PeriodName>
      <StartDate>-500000</StartDate>
      <EndDate>43</EndDate>
    </Period>
    <Period>
      <PeriodName>Iron Age</PeriodName>
      <StartDate>-800</StartDate>
      <EndDate>43</EndDate>
    </Period>
    <Period>
      <PeriodName>Roman</PeriodName>
      <StartDate>43</StartDate>
      <EndDate>410</EndDate>
    </Period>
  </PeriodGroup>
  <PeriodGroup name="CAFG">
    <Period>
      <PeriodName>Prehistoric</PeriodName>
      <StartDate>-500000</StartDate>
      <EndDate>43</EndDate>
    </Period>
    <Period>
      <PeriodName>Roman</PeriodName>
      <StartDate>43</StartDate>
      <EndDate>410</EndDate>
    </Period>
    <Period>
      <PeriodName>Anglo-Saxon</PeriodName>
      <StartDate>410</StartDate>
      <EndDate>800</EndDate>
    </Period>   
  </PeriodGroup>
</Periods>

我需要能够读取所选PeriodGroup中的Period节点子级.我想,如果更明智的话,PeriodName可能是Period的属性.

I need to be able to read the Period node children within a selected PeriodGroup. I guess the PeriodName could be an attribute of Period if that is more sensible.

我查看了很多示例,但似乎没有一个是正确的,似乎有数十种不同的方法,有些使用XmlReader,有些使用XmlTextReader,而有些则不使用.因为这是我第一次阅读Xml文件,所以我想问一下是否有人可以给我一个指针.我有一些可以尝试的东西,但是感觉很笨拙.我正在使用VS2010和c#.另外,我看到很多人都在使用LINQ-Xml,因此,我感谢使用此方法的利弊.

I have looked at loads of examples but none seem to be quite right and there seems to be dozens of different methods, some using XmlReader, some XmlTextReader and some not using either. As this is my first time reading an Xml file, I thought I'd ask if anyone could give me a pointer. I've got something working just to try things out, but it feels clunky. I'm using VS2010 and c#. Also, I see a lot of people are using LINQ-Xml, so I'd appreciate the pros and cons of using this method.

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 + "<br>" + node2["PeriodName"].InnerText;
            text = text + "<br>" + node2["StartDate"].InnerText;
            text = text + "<br>" + node2["EndDate"].InnerText;
        }
    }
    Response.Write(text);
}

推荐答案

您可以这样使用XPath方法:

You could use an XPath approach like so:

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

尽管LINQ比XML更易读,但是更喜欢LINQ.

Though prefer LINQ to XML for it's readability.

这将根据提供的 PeriodGroup name 属性返回 Period 节点子级,例如 HER :

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

结果:

<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>

查询非常简单

from n in xml.Descendants("Periods")

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

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"

然后将集合过滤为具有 name 属性且值为 HER

Will then filter down the collection to PeriodGroup elements that have a name attribute with a value of HER

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

Finally, we select the PeriodGroup element and get it's descendant nodes

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

编辑(查看评论)

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

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

这是查询运行后 nodes 对象的外观:

This is what the nodes object will look like after the query has run:

这篇关于读取xml文件的多个子节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆