Ok, I've got the following XML tree
好的,我有以下XML树
<root>
<A>
<A1>
<A1A>1000</A1A>
<A1B>2000</A1B>
<A1C>3000</A1C>
</A1>
<A2>
<A2A>4000</A2A>
<A2B>5000</A2B>
</A2>
</A>
<B>
<B1>
<B1A>6000</B1A>
</B1>
</B>
</root>
From a method receiving an XDocument I want to produce a dictionary where the key is the path (really an XPath) and the value comes from the value in the corresponding leaf.
从接收XDocument的方法我想生成一个字典,其中键是路径(实际上是XPath),值来自相应叶子中的值。
root/A/A1/A1A 1000
root/A/A1/A1B 2000
root/A/A1/A1C 3000
root/A/A2/A2A 4000
root/A/A2/A2B 5000
root/B/B1/B1A 6000
Seems simple to do in Linq to XML but I can't wrap my head around it.
在Linq to XML中似乎很简单,但我无法理解它。
2 个解决方案
#1
9
You can find the leaves by looking for elements that have no descendants:
您可以通过查找没有后代的元素来查找叶子:
var doc = XDocument.Load(fileName);
var leaves =
from e in doc.Descendants()
where !e.Elements().Any()
select e;
I don't know if there is a built-in way to get the path of an element, but you can easily create an extension method to build it:
我不知道是否有内置的方法来获取元素的路径,但您可以轻松地创建一个扩展方法来构建它:
static class Extensions
{
public static string Path(this XElement element)
{
XElement tmp = element;
string path = string.Empty;
while (tmp != null)
{
path = "/" + tmp.Name + path;
tmp = tmp.Parent;
}
return path;
}
}
You can then build the dictionary like this:
然后,您可以像这样构建字典:
var dict = leaves.ToDictionary(e => e.Path(), e => e.Value);
#2
2
After parsing the XML to an XDocument, which I assume you've already been able to do, use the methods below. Note that the GetPath()
implementation is fairly naiive. See this answer for a better implementation.
在将XML解析为XDocument之后,我假设您已经能够执行此操作,请使用以下方法。请注意,GetPath()实现非常简单。请参阅此答案以获得更好的实施。
public Dictionary<string, string> GetLeaves(XDocument doc)
{
var dict = doc
.Descendants()
.Where(e => !e.HasElements)
.ToDictionary(e => GetPath(e), e.Value);
return dict;
}
private string GetPath(XElement element)
{
var nodes = new List<string>();
var node = element;
while (node != null)
{
nodes.Add(node.Name.ToString());
node = node.Parent;
}
return string.Join("/", Enumerable.Reverse(nodes));
}
#1
9
You can find the leaves by looking for elements that have no descendants:
您可以通过查找没有后代的元素来查找叶子:
var doc = XDocument.Load(fileName);
var leaves =
from e in doc.Descendants()
where !e.Elements().Any()
select e;
I don't know if there is a built-in way to get the path of an element, but you can easily create an extension method to build it:
我不知道是否有内置的方法来获取元素的路径,但您可以轻松地创建一个扩展方法来构建它:
static class Extensions
{
public static string Path(this XElement element)
{
XElement tmp = element;
string path = string.Empty;
while (tmp != null)
{
path = "/" + tmp.Name + path;
tmp = tmp.Parent;
}
return path;
}
}
You can then build the dictionary like this:
然后,您可以像这样构建字典:
var dict = leaves.ToDictionary(e => e.Path(), e => e.Value);
#2
2
After parsing the XML to an XDocument, which I assume you've already been able to do, use the methods below. Note that the GetPath()
implementation is fairly naiive. See this answer for a better implementation.
在将XML解析为XDocument之后,我假设您已经能够执行此操作,请使用以下方法。请注意,GetPath()实现非常简单。请参阅此答案以获得更好的实施。
public Dictionary<string, string> GetLeaves(XDocument doc)
{
var dict = doc
.Descendants()
.Where(e => !e.HasElements)
.ToDictionary(e => GetPath(e), e.Value);
return dict;
}
private string GetPath(XElement element)
{
var nodes = new List<string>();
var node = element;
while (node != null)
{
nodes.Add(node.Name.ToString());
node = node.Parent;
}
return string.Join("/", Enumerable.Reverse(nodes));
}