如何从XML读取属性值并将它们组合成一个字符串

时间:2017-02-15 14:53:34

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

编辑:目前为止,提议的答案对我不起作用。也许我的例子有点误导。我已经更新了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读取整个文件,并获得一个字符串&#34; main-node&#34;这是根据属性名称&#39;每个&#34;子节点&#34;。所以结果应该是这样的:

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"

我的问题是我不知道如何才能完成这项工作。 任何人都可以告诉我一个如何完成这项工作的例子吗?

3 个答案:

答案 0 :(得分:2)

您可以执行以下操作:

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()循环遍历根元素<VariableCollection>的直接子元素,然后为每个元素递归地使用DescendantsAndSelf()下降其元素层次结构以选择Name嵌套查询中的属性,然后将值与String.Join()组合。

示例fiddle

答案 1 :(得分:1)

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

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

生成输出:

lastLevel:

<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小提琴

答案 2 :(得分:0)

您可以使用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");