LINQ是否有一种简单的方法可以展平XML文件?
我可以通过XSLT看到很多方法,但想知道LINQ的最佳选择是什么?
我无法完全放弃xml结构,因为stackoverflow似乎过滤了雪佛龙字符。但是这样的事情
nodeA
- nodeA1
- nodeA2
NodeB
我想以
结束nodeA
nodeA1
nodeA2
节点B
答案 0 :(得分:1)
行;它取决于你想要的输出 - 使用XElement你需要做一些工作来删除所有后代节点等。但是,它实际上非常简单的XmlDocument:
string xml = @"<xml><nodeA><nodeA1/><nodeA2/></nodeA><NodeB/></xml>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
XmlDocument clone = new XmlDocument();
XmlElement root = (XmlElement) clone.AppendChild(clone.CreateElement("xml"));
foreach(XmlElement el in doc.SelectNodes("//*")) {
root.AppendChild(clone.ImportNode(el, false));
}
Console.WriteLine(clone.OuterXml);
输出:
<xml><xml /><nodeA /><nodeA1 /><nodeA2 /><NodeB /></xml>
[是] 在这种背景下关心定义“扁平化”?即“之前”和“之后”? XDocument有Descendants()和DescendantNodes()可以完成这项工作......
答案 1 :(得分:1)
使用扩展方法这很容易做到:
public static class XElementExtensions
{
public static string Path(this XElement xElement)
{
return PathInternal(xElement);
}
private static string PathInternal(XElement xElement)
{
if (xElement.Parent != null)
return string.Concat(PathInternal(xElement.Parent), ".", xElement.Name.LocalName);
return xElement.Name.LocalName;
}
}
然后:
private static void Main()
{
string sb =@"<xml>
<nodeA>
<nodeA1>
<inner1/><inner2/>
</nodeA1>
<nodeA2/>
</nodeA>
<NodeB/>
</xml>";
XDocument xDoc = XDocument.Parse(sb);
var result = xDoc.Root.Descendants()
.Select(r => new {Path = r.Path()});
foreach (var p in result)
Console.WriteLine(p.Path);
}
结果:
xml.nodeA
xml.nodeA.nodeA1
xml.nodeA.nodeA1.inner1
xml.nodeA.nodeA1.inner2
xml.nodeA.nodeA2
xml.NodeB
答案 2 :(得分:0)
Marc所说的最后一部分是我认为你正在寻找的东西。这是一个示例,您可以放入LINQPad并查看“展平”的结果。
string xml = @"<xml><nodeA><nodeA1><inner1/><inner2/></nodeA1><nodeA2/></nodeA><NodeB/></xml>";
XDocument doc = XDocument.Parse(xml);
doc.Dump();
doc.Root.Descendants().Dump();
doc.Descendants().Dump();
doc.Root.Descendants().Count().Dump();
doc.Descendants().Count().Dump();