簡體   English   中英

讀取xml文件的多個子節點

[英]Reading multiple child nodes of xml file

我創建了一個帶有示例內容的Xml文件,如下所示:

<?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的一個屬性,如果這更合理的話。

我看了很多例子,但似乎沒有一點是正確的,似乎有幾十種不同的方法,一些使用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 + "<br>" + node2["PeriodName"].InnerText;
            text = text + "<br>" + node2["StartDate"].InnerText;
            text = text + "<br>" + 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();

結果:

<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根據屬性值過濾這個節點集合:

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 += "<br>" + n.PeriodName;
      text += "<br>" + n.StartDate;
      text += "<br>" + 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 <Period> child of the relevant <PeriodGroup>.
}

您可以在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);
                    }

                }
            }
        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM