使用 linq to xml 按元素展平 XML 结构

发布于 2025-01-04 16:19:08 字数 2265 浏览 1 评论 0原文

我最近创建了一篇关于展平 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>[email protected]</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>[email protected]</email>
    </member>
</members>

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

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

I recently created a post about flattening an XML structure so every element and it's values were turned into attributes on the root element. Got some great answer and got it working. However, sad thing is that by flattening, the client meant to flatten the elements and not make them into attributes :-/

What I have is this:

<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>[email protected]</email>
            </contact>
        </kontakter>
    </member>
</members>

And what I need is the following:

<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>[email protected]</email>
    </member>
</members>

So basically all elements, but flattened as childnodes of . I do know that it's not pretty at all to begin parsing XML documents like this, but it's basically the only option left as the CMS we're importing data to requires this flat structure and the XML document comes from an external webservice.

I started to make a recursive method for this, but I've got an odd feeling that it could be made smoother (well, as smooth as possible at least) with some LINQ to XML (?) I'm not the best at linq to xml, so I hope there's someone out there who would be helpful to give a hint on how to solve this? :-)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

我喜欢麦丽素 2025-01-11 16:19:08

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

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);

This seems to work - there may be neater approaches, admittedly:

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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文