【问题标题】:How to read attribute values from XML and combine them to one string如何从 XML 中读取属性值并将它们组合成一个字符串
【发布时间】:2017-02-15 14:53:33
【问题描述】:

编辑:到目前为止,建议的答案对我不起作用。也许我的例子有点误导。我已经更新了 XML 以及预期的字符串以供参考。我可以多次出现具有不同级别的节点,并且在每个级别中我可以有一个或多个子节点。

我有一个具有以下结构的 XML 文件:

<VariableCollection>
    <Variable Name="Level1">
         <Variable Name="Level2">
               <Variable Name="Level3">
                   <Variable Name="Level4"/>
                   <Variable Name="Level41"/>
               </Variable>
         </Variable>
    </Variable>
    <Variable Name="Level11">
         <Variable Name="Level21">
               <Variable Name="Level31">
                   <Variable Name="Level41"/>
                   <Variable Name="Level42"/>
                   <Variable Name="Level43"/>
               </Variable>
         </Variable>
    </Variable>
    <Variable Name="Level1">
          <Variable Name="Level2">
               <Variable Name="Level3"/>
          </Variable>
    </Variable>
    <Variable Name="Level11">
          <Variable Name="Level21">
               <Variable Name="Level31"/>
          </Variable>
    </Variable>
    <Variable Name="Level1">
          <Variable Name="Level2"/>
    </Variable>
    <Variable Name="Level11">
          <Variable Name="Level21"/>
    </Variable>
</VariableCollection>

所以我有具有不同结构化子级别/子节点的节点。 我想要做的是使用 LINQ to XML 读取整个文件,并从每个“子节点”的属性“名称”创建的每个“主节点”获取一个字符串。所以结果应该是这样的:

string1 = "Level1.Level2.Level3.Level4"
string11 = "Level1.Level2.Level3.Level41"

string2 = "Level11.Level21.Level31.Level41"
string22 = "Level11.Level21.Level31.Level42"
string23 = "Level11.Level21.Level31.Level43"

string3 = "Level1.Level2.Level3"
string3 = "Level11.Level21.Level31"

string4 = "Level1.Level2"
string5 = "Level11.Level21"

我的问题是我不知道如何才能完成这项工作。 谁能给我举个例子,我怎么能做到这一点?

【问题讨论】:

    标签: c# .net xml linq linq-to-xml


    【解决方案1】:

    您可以执行以下操作:

    var root = XDocument.Parse(xml);
    var strings = root.Root.Elements()
        .Select(e => String.Join(".", e.DescendantsAndSelf().Select(c => (string)c.Attribute("Name"))))
        .ToArray();
    

    在这里,我使用XElement.Elements() 循环遍历根元素&lt;VariableCollection&gt; 的直接子元素,然后使用DescendantsAndSelf() 递归地降低每个元素的元素层次结构,以在嵌套查询中挑选出Name 属性,然后组合String.Join() 的值。

    例如fiddle

    【讨论】:

      【解决方案2】:

      我使用“自下而上”的方法。第一步是找到没有嵌套元素的变量(代码中的lastLvl)。第二步是遍历根并连接名称。以下代码

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.Xml.Serialization;
      using System.Xml;
      using System.Xml.Linq;
      using System.Xml.XPath;
      using System.Collections;
      
      public class Program
      {
          public static void Main()
          {
              var @s = 
      @"<VariableCollection>
          <Variable Name='Level1'>
               <Variable Name='Level2'>
                     <Variable Name='Level3'>
                         <Variable Name='Level4'/>
                         <Variable Name='Level41'/>
                     </Variable>
               </Variable>
          </Variable>
          <Variable Name='Level11'>
               <Variable Name='Level21'>
                     <Variable Name='Level31'>
                         <Variable Name='Level41'/>
                         <Variable Name='Level42'/>
                         <Variable Name='Level43'/>
                     </Variable>
               </Variable>
          </Variable>
          <Variable Name='Level1'>
                <Variable Name='Level2'>
                     <Variable Name='Level3'/>
                </Variable>
          </Variable>
          <Variable Name='Level11'>
                <Variable Name='Level21'>
                     <Variable Name='Level31'/>
                </Variable>
          </Variable>
          <Variable Name='Level1'>
                <Variable Name='Level2'/>
          </Variable>
          <Variable Name='Level11'>
                <Variable Name='Level21'/>
          </Variable>
      </VariableCollection>";
      
              var xml = XElement.Parse(@s);
      
              var lastLvl = xml.Descendants("Variable").Where(x => !x.HasElements);
      
              Console.WriteLine(String.Join(Environment.NewLine, lastLvl));
      
              var names = lastLvl.Select(x => String.Join(".", x.AncestorsAndSelf("Variable").Select(e=>(string)e.Attribute("Name")).Reverse()));
      
              Console.WriteLine();
              Console.WriteLine(String.Join(Environment.NewLine, names));
          }
      }
      

      生成输出:

      最后一层:

      <Variable Name="Level4" />
      <Variable Name="Level41" />
      <Variable Name="Level41" />
      <Variable Name="Level42" />
      <Variable Name="Level43" />
      <Variable Name="Level3" />
      <Variable Name="Level31" />
      <Variable Name="Level2" />
      <Variable Name="Level21" />
      

      名字:

      Level1.Level2.Level3.Level4
      Level1.Level2.Level3.Level41
      Level11.Level21.Level31.Level41
      Level11.Level21.Level31.Level42
      Level11.Level21.Level31.Level43
      Level1.Level2.Level3
      Level11.Level21.Level31
      Level1.Level2
      Level11.Level21
      

      试试Demo小提琴

      【讨论】:

        【解决方案3】:

        你可以像这样使用XElement来解析和遍历文档:

        string xml = @"
        <VariableCollection>
            <Variable Name=""Level1"">
                 <Variable Name=""Level2"">
                       <Variable Name=""Level3"">
                           <Variable Name=""Level4""/>
                       </Variable>
                 </Variable>
            </Variable>
            <Variable Name=""Level1"">
                  <Variable Name=""Level2"">
                       <Variable Name=""Level3""/>
                  </Variable>
            </Variable>
            <Variable Name=""Level1"">
                  <Variable Name=""Level2""/>
            </Variable>
        </VariableCollection>
        ";
        
        var root  = XElement.Parse(xml);
        
        var stringList = new List<string>();
        foreach (var child in root.Elements())
        {
            string value = child.DescendantsAndSelf()
                .Select(i => i.Attribute("Name").Value)
                .Aggregate((a, b) => a + "." + b);
        
            stringList.Add(value);
        }
        
        foreach (var str in stringList)
            Console.WriteLine(str.ToString());
        

        如果你想从一个文件中加载,那么我们这个代码:

        var root = XElement.Load("filepath");
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-06-14
          • 2014-04-15
          • 1970-01-01
          • 1970-01-01
          • 2018-12-14
          • 1970-01-01
          • 2017-04-03
          • 1970-01-01
          相关资源
          最近更新 更多