使用LINQ简化XML文件的方法

时间:2008-10-21 10:12:45

标签: xml linq

LINQ是否有一种简单的方法可以展平XML文件?

我可以通过XSLT看到很多方法,但想知道LINQ的最佳选择是什么?

我无法完全放弃xml结构,因为stackoverflow似乎过滤了雪佛龙字符。但是这样的事情

nodeA

- nodeA1

- nodeA2

NodeB

我想以

结束

nodeA

nodeA1

nodeA2

节点B

3 个答案:

答案 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();