【问题标题】:How can I iterate though each child node in an XML file?如何遍历 XML 文件中的每个子节点?
【发布时间】:2018-09-13 21:08:13
【问题描述】:

我有一个 XML 文件,我想遍历收集信息的每个子节点。

这是我的 C# 代码,它只选择一个节点,即我想在其子节点上使用 foreach 的 FieldData。

public void LoadXML() {
    if (File.Exists("Data.xml")) {
        //Reading XML
        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.Load("Data.xml");

        //Think something needs to reference Child nodes, so i may Foreach though them

        XmlNodeList dataNodes = xmlDoc.SelectNodes("//FieldData"); 
        TagContents[] ArrayNode;

        foreach(XmlNode node in dataNodes) {
            int Count = 0;
            //int Max = node.ChildNodes.Count;
            ArrayNode = new TagContents[Max];

            ArrayNode[Count].TagName = node.Name;
            ArrayNode[Count].TagValue = node.SelectSingleNode(ArrayNode[Count].TagName).InnerText;
            Count = Count + 1;        
        }
    } else {
        MessageBox.Show("Could not find file Data.xml");
    }
}

我的 XML 看起来像这样:

<?xml version="1.0"?>
<FieldData>
  <property_details_branch IncludeInPDFExport="Yes" Mod="20010101010101"/>
  <property_details_inspection_date IncludeInPDFExport="Yes" Mod="20120726200230">20120727220230+0200</property_details_inspection_date>
  <property_details_type_of_ownership IncludeInPDFExport="Yes" Mod="20120726134107">Freehold</property_details_type_of_ownership>
</FieldData>

【问题讨论】:

  • 我只想指出,在您的 foreach 循环中,您将 Count 设置为零,执行操作,将其递增并设置回零。

标签: c# xml


【解决方案1】:

您正在迭代 FieldData 节点,而您只有一个。要迭代其子节点,请编写:

foreach (XmlNode node in dataNodes)
{
     foreach (XmlNode childNode in node.ChildNodes)
     {

【讨论】:

  • 不应该是foreach(node.ChildNodes中的XmlNode childNode)吗?
  • 我建议您查看有关 XDocument 的其他答案。您应该使用它而不是 XmlDocument。
  • 请注意,如果有人决定在 下添加 cmets 或文本节点,您的循环也会选择这些。
  • 我认为,这段代码只会迭代到第 2 级。如果它们是 2 级的子子级,则不会给出值。
【解决方案2】:

对于这种事情,我一般更喜欢Linq-To-Xml

  var doc = XDocument.Load("XMLFile1.xml");
  foreach (var child in doc.Element("FieldData").Elements())
  {
    Console.WriteLine(child.Name);
  }

【讨论】:

    【解决方案3】:

    或者你使用递归:

        public void findAllNodes(XmlNode node)
        {
            Console.WriteLine(node.Name);
            foreach (XmlNode n in node.ChildNodes)
                findAllNodes(n);
        }
    

    您将有效负载放置在哪里取决于您要使用哪种搜索(例如广度优先搜索、深度优先搜索等;请参阅http://en.wikipedia.org/wiki/Euler_tour_technique

    【讨论】:

      【解决方案4】:

      你可以这样做:

          XDocument doc = XDocument.Load(@"Data.xml");
          TagContents[] ArrayNode = doc.Root
                                      .Elements()
                                      .Select(el =>
                                          new TagContents()
                                          {
                                              TagName = el.Name.ToString(),
                                              TagValue = el.Value
                                          })
                                      .ToArray();
      

      【讨论】:

        【解决方案5】:

        刚刚谈到@Waynes 的回答,效果很好。我使用下面的代码进一步推入我的 xml 中的子节点

        foreach (var child in doc.Element("rootnodename").Element("nextchildnode").Elements()) 
        
        {
        
         //do work here, probs async download xml content to file on local disc
        
        } 
        

        【讨论】:

          【解决方案6】:
              public void ValidateXml(string[] Arrays)
              {                                         
                  foreach (var item in Arrays)
                  {
                      Xdoc.Load(item);                              
                      XmlNodeList xnList = Xdoc.SelectNodes("FirstParentNode");
                      if (xnList.Count > 0)
                      {
                          foreach (XmlNode xn in xnList)
                          {
                              XmlNodeList anode = xn.SelectNodes("SecondParentNode");
                              if (anode.Count > 0)
                              {
                                  foreach (XmlNode bnode in anode)
                                  {                               
                                      string InnerNodeOne = bnode["InnerNode1"].InnerText;
                                      string InnerNodeTwo = bnode["InnerNode1"].InnerText;
          
                                  }                           
                              }
                              else
                              {
                                  ErrorLog("Parent Node DoesNot Exists");                                                 
                              }
                          }                  
                      }
                      else
                      {
                          ErrorLog("Parent Node DoesNot Exists");
                      }
          
                  }
                 //then insert or update these values in database here
              }
          

          【讨论】:

          • 什么是父节点的层级更多?我想你的代码到时候会坏掉。
          【解决方案7】:

          要遍历每个子节点,子子节点等等,我们必须使用Recursion。如果有人和我有同样的要求,我实现了如下 -

          public string ReadAllNodes(XmlNode node)
          {
              if (node.ChildNodes.Count > 0)
              {
                  foreach (XmlNode subNode in node)
                  {
                      //Recursion
                      ReadAllNodes(subNode);
                  }
              }
              else //Get the node value.
              {
                  finalText = finalText + node.InnerText + System.Environment.NewLine;
              }
              return finalText;
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-08-04
            • 2011-09-11
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多