【问题标题】:Flatten XML structure by element with linq to xml使用 linq to xml 按元素展平 XML 结构
【发布时间】:2012-03-02 07:50:06
【问题描述】:

我最近创建了一篇关于扁平化 XML 结构的帖子,以便将每个元素及其值转换为根元素上的属性。得到了一些很好的答案并让它工作。然而,可悲的是,通过扁平化,客户端意味着扁平化元素而不是将它们变成属性:-/

我拥有的是这样的:

<members>
    <member xmlns="mynamespace" id="1" status="1">
       <sensitiveData>
           <notes/>
           <url>someurl</url>
           <altUrl/>
           <date1>somedate</date1>
            <date2>someotherdate</date2>
            <description>some description</description>
            <tags/>
            <category>some category</category>
        </sensitiveData>
        <contacts>
            <contact contactId="1">
                <contactPerson>some contact person</contactPerson>
                <phone/>
                <mobile>mobile number</mobile>
                <email>some@email.com</email>
            </contact>
        </kontakter>
    </member>
</members>

我需要的是以下内容:

<members>
    <member xmlns="mynamespace" id="1" status="1">
        <sensitiveData/>
        <notes/>
        <url>someurl</url>
        <altUrl/>
        <date1>somedate</date1>
        <date2>someotherdate</date2>
        <description>some description</description>
        <tags/>
        <category>some category</category>
        <contacts/>
        <contact contactId="1"></contact>
        <contactPerson>some contact person</contactPerson>
        <phone/>
        <mobile>mobile number</mobile>
        <email>some@email.com</email>
    </member>
</members>

所以基本上所有元素,但扁平化为 .我知道像这样开始解析 XML 文档一点也不漂亮,但它基本上是唯一的选择,因为我们要导入数据的 CMS 需要这种扁平结构,而 XML 文档来自外部 Web 服务。

我开始为此创建一个递归方法,但我有一种奇怪的感觉,它可以通过一些 LINQ to XML 变得更平滑(嗯,至少尽可能平滑)(?)我不是最擅长 linq to xml,所以我希望有人能帮助提示如何解决这个问题? :-)

【问题讨论】:

    标签: c# xml linq-to-xml xml-parsing


    【解决方案1】:

    这似乎可行 - 诚然,可能会有更简洁的方法:

    var doc = XDocument.Load("test.xml");
    XNamespace ns = "mynamespace";
    var member = doc.Root.Element(ns + "member");
    
    // This will *sort* of flatten, but create copies...
    var descendants = member.Descendants().ToList();
    
    // So we need to strip child elements from everywhere...
    // (but only elements, not text nodes). The ToList() call
    // materializes the query, so we're not removing while we're iterating.
    foreach (var nested in descendants.Elements().ToList())
    {
        nested.Remove();
    }
    member.ReplaceNodes(descendants);
    

    【讨论】:

    • 嗨乔恩,这确实有效!非常感谢 :) 我似乎无法弄清楚的唯一一件事(请耐心等待,在 XML 解析方面我不是最锋利的刀)是如何保留元素的属性。当您复制元素时,它们似乎被删除了? :)
    • @bomortensen:在这种情况下,它们似乎没有被删除 - 例如,我仍然有 contactId="1" ......哦,我刚刚注意到它已经删除了属性来自member 元素本身。会解决的,等一下。
    • @bomortensen:是的,已修复 - 最后一行现在是 ReplaceNodes,而不是 ReplaceAll
    • 有趣的是foreach (var descendant in descendants)中的descendant从未被使用过。
    • @Meysam:这是一个错误 - 哎呀!否则它不会为深度嵌套的元素做正确的事情。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多