如何从 XML 中读取属性值并将它们组合成一个字符串
How to read attribute values from XML and combine them to one string
编辑: 到目前为止,建议的答案对我不起作用。也许我的例子有点误导。我已经更新了 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>
所以我的节点具有不同的结构子 levels/child 节点。
我想要做的是使用 LINQ to XML 读取整个文件,并从每个 "sub-node" 的属性 'Name' 创建的每个 "main-node" 获取一个字符串。所以结果应该是这样的:
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"
我的问题是我不知道如何完成这项工作。
谁能告诉我如何完成此操作的示例?
您可以使用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");
您可以执行以下操作:
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()
, then for each element recursively descent its element hierarchy with DescendantsAndSelf()
to pick out the Name
attributes in a nested query, then combine the values with String.Join()
.
遍历根元素 <VariableCollection>
的直接子元素
示例 fiddle.
我使用了"bottom-up"方法。第一步是找到没有嵌套元素的变量(代码中的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 fiddle
编辑: 到目前为止,建议的答案对我不起作用。也许我的例子有点误导。我已经更新了 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>
所以我的节点具有不同的结构子 levels/child 节点。 我想要做的是使用 LINQ to XML 读取整个文件,并从每个 "sub-node" 的属性 'Name' 创建的每个 "main-node" 获取一个字符串。所以结果应该是这样的:
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"
我的问题是我不知道如何完成这项工作。 谁能告诉我如何完成此操作的示例?
您可以使用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");
您可以执行以下操作:
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()
, then for each element recursively descent its element hierarchy with DescendantsAndSelf()
to pick out the Name
attributes in a nested query, then combine the values with String.Join()
.
<VariableCollection>
的直接子元素
示例 fiddle.
我使用了"bottom-up"方法。第一步是找到没有嵌套元素的变量(代码中的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 fiddle