【问题标题】:How to read a particular node from xml in C#?如何从 C# 中的 xml 读取特定节点?
【发布时间】:2013-04-22 12:28:51
【问题描述】:

我有以下 XML:

<Loop Name="MasterData">
  <Loop Name="SlaveData">
    <Segment Name="AAA">
      <Node1>hello</Node1>
      <Node2>john</Node2>
      <Node3>hi</Node3>
      <Node4>marry</Node4>
    </Segment>
    <Segment Name="BBB">
      <Node1>00</Node1>
      <Node2> </Node2>
      <Node3>00</Node3>
      <Node4> </Node4>
    </Segment> 
   </Loop>
</Loop>

我必须读取每个节点的值,即 Node1、Node2、Node3、Node4,它们位于 Segment 节点下,其属性为 Name = "AAA"。我怎样才能做到这一点。我指的是stackoverflow的以下链接,但这对我不起作用。

How to read attribute value from XmlNode in C#?

我需要这样的输出

让我有四个变量strNode1, strNode2, strNode3, strNode4。我想将值存储在上述四个变量中,如下所示

strNode1 = "hello"
strNode2 = "john"
strNode3 = "hi"
strNode4  = "marry"

【问题讨论】:

  • “不工作”不是错误描述。请显示您尝试过的代码并告诉我们它的问题所在。

标签: c# asp.net .net


【解决方案1】:

您可以使用XmlDocument 将您的xml 作为对象加载,然后使用XPath 查询您想要的特定节点。您的 xpath 查询(我现在无法测试)可能看起来像这样。

XmlNodeList xNodes = xmlDocument.SelectNodes("//Segment[@Name = 'AAA']");

【讨论】:

  • SelectNodes 返回 XmlNodeList,而不是 XmlNode
  • 您可以在 XPath 中更进一步,因为 OP 只需要使用 node() 函数和 Cast Xlinq 函数的 innerText。 IE。 dom.SelectNodes("//Segment[@Name = 'AAA']/node()").Cast().Select(n => n.InnerText).ToList()
【解决方案2】:

我为我的问题找到了一个简单的解决方案

XmlNodeList xnList = doc.SelectNodes("/Loop/Loop/Segment[@Name='AAA']");
          foreach (XmlNode xn in xnList)
          {
              if (xn.HasChildNodes)
              {
                  foreach (XmlNode item in xn.ChildNodes)
                  {
                      Console.WriteLine(item.InnerText);
                  }
              }  
          }

【讨论】:

    【解决方案3】:

    我建议使用 XDocument(省略了基于父节点等的 NB 特定过滤):

    var document = XDocument.Load(path);
    var nodes = document.Descendents().Where(e => e.Name.LocalName.StartsWith("Node"));
    

    更新以包含父元素的过滤

    var nodes = document.Descendents()
                        .Where(e => e.Atrributes().Any(a => a.Name.localName == "Name" && a.Value == "AAA"))
                        .SelectMany(e => e.Descendents().Where(e => e.Name.LocalName.StartsWith("Node"));
    var values = nodes.Select(n => n.Value).ToList(); // This will be a list containing "hello", "john, "hi", "marry"
    

    【讨论】:

    • 我必须阅读 Node1、Node2、Node3、Node4,它们位于 Name = "AAA" 的段下。我认为您的解决方案将尝试读取所有节点元素
    • 你考虑过过滤吗?
    • 答案现已更新,包括值的过滤和选择。 NB 很少对 xml 的结构做出假设,所有作为具有“AAA”名称属性的元素的后代的元素都是合格的,而不仅仅是那些属于 Loop -&gt; Loop -&gt; Segment 层次结构的元素
    【解决方案4】:

    假设你有一个XmlDocument,你可以像这样使用 XPath:

    XmlNode node = doc.SelectSingleNode("//Segment[@Name='AAA']");
    

    获取Segment 节点,然后在循环中迭代其所有子节点。

    【讨论】:

      【解决方案5】:

      您可以使用 XmlDocument 和 XPath:

      XmlDocument doc = new XmlDocument();
      doc.Load(xml);
      foreach(XmlNode node in doc.SelectNodes("//Segment[@Name='AAA']/node()"))
      {
          string name = node.Name;
          string value = node.innerText;
          // ...
      }
      

      【讨论】:

      • 由于 OP 只想要 innerText,您可以通过将 XmlNodeList 转换为 IEnumerable 然后投影出 InnerText 来使 foreach 语句更简洁,即 dom.SelectNodes("//Segment[ @Name = 'AAA']/node()").Cast().Select(n => n.InnerText).ToList()
      【解决方案6】:

      试试这个:

      System.Xml.Linq.XDocument doc = XDocument.Load(your file);
      
      var nodes = 
           doc.Element("Loop").Element("Loop").Elements("Segment")
                      .Where(input => (string)input.Attribute("Name") == "AAA")
                      .Select(input => input.Elements()).ToList();
      

      然后:

      List<string> result = new List<string>();
      
      foreach (List<XElement> item in nodes)
      {
          result.AddRange(item.Select(i => i.Value));
      }
      

      【讨论】:

      • 请改用(string)input.Attribute("Name") == "AAA"。如果至少存在一个没有"Name" 属性的Segment 节点,您的代码将引发异常。
      • @HosseinNarimaniRad - 感谢它的工作,但是如何遍历所有选择的节点以获取字符串中所有节点的值?
      • @NareshKumar 编辑您的帖子并考虑编写您希望达到的字符串输出。
      • @HosseinNarimaniRad - 我已经编辑了我的帖子。基本上我想知道如何使用 foreach 循环迭代节点变量中的元素?
      【解决方案7】:

      如果您曾经使用过 linq-to-entities 或 linq-to-sql,则可以使用 linq-to-xml

      【讨论】:

        【解决方案8】:

        你可以试试这个吗?

        XDocument xmlFile = XDocument.Load("myFile.xml");
        foreach (var nodeSegment in xmlFile.Descendants("Loop"))
        {
           foreach (var nodes in nodeSegment.Descendants().Where(e => e.Name.LocalName.StartsWith("Node")))
           {
        
           }
        }
        

        【讨论】:

          【解决方案9】:

          试试这个..

          List<string> nodeDetails = new List<string>();
          
                 var nodes = from n in XDocument.Load(@"D:\pfXml.xml")
                                                        .Element("Loop")
                                                        .Element("loop")
                                                        .Elements("Segment")
                                                where (string)n.Attribute("Name") == "AAAA"
                                                select new
                                                {
                                                    n1 = n.Element("Node1").Value,
                                                    n2 = n.Element("Node2").Value,
                                                    n3 = n.Element("Node3").Value,
                                                    n4 = n.Element("Node4").Value
                                                };
                  foreach (var node in nodes)
                  {
                      nodeDetails.Add(node.n1);
                      nodeDetails.Add(node.n2);
                      nodeDetails.Add(node.n3);
                      nodeDetails.Add(node.n4);
                  }
          

          【讨论】:

            猜你喜欢
            • 2015-12-18
            • 1970-01-01
            • 1970-01-01
            • 2022-11-10
            • 2013-10-22
            • 2010-11-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多