从结果集创建 xml 节点树,但使用 linq 或表达式组合重复的属性

发布于 2024-10-31 01:43:25 字数 1233 浏览 0 评论 0原文

您好,我有一个以下格式的数据集:

NodeID | NodeName | NodeAttribute1 | NodeAttribute2
   1   |    n1    |       1        |      null
   2   |    n2    |       1        |      null
   3   |    n3    |       1        |        1
   4   |    n4    |       2        |        2
   5   |    n5    |       2        |        3
   6   |    n6    |       2        |        4

基本上,属性决定节点在虚拟树中的位置。我希望结果如下所示:

<NodeTree>
    <ParentNodeType1 NodeAttribute1 = 1> 
        <node name="n1" nodeID=1>
        <node name="n2" nodeID=2>
        <ParentNodeType2 NodeAttribute2 = 1>
            <node name = "n3" nodeID = 3>
        </ParentNodeType2>
    </ParentNodeType1>
    <ParentNodeType1 NodeAttribute1 = 2> 
        <ParentNodeType2 NodeAttribute2 = 3>
            <node name = "n4" nodeID=4>
        </ParentNodeType2>
        <ParentNodeType2 NodeAttribute2 = 4>
            <node name = "n5" nodeID=5>
            <node name = "n6" nodeID=6>
        </ParentNodeType2>
    </ParentNodeType1>
</NodeTree>

因此 n1 和 n2 在parent1 中,但 n3 更深一层,因为第二个属性不为空。有人对如何使用 linq 或类似的东西来完成这个有任何想法吗?

Hi I have a dataset in the following format:

NodeID | NodeName | NodeAttribute1 | NodeAttribute2
   1   |    n1    |       1        |      null
   2   |    n2    |       1        |      null
   3   |    n3    |       1        |        1
   4   |    n4    |       2        |        2
   5   |    n5    |       2        |        3
   6   |    n6    |       2        |        4

Basically, the attributes determine the position of the node in the virtual tree. I want the result to look like this:

<NodeTree>
    <ParentNodeType1 NodeAttribute1 = 1> 
        <node name="n1" nodeID=1>
        <node name="n2" nodeID=2>
        <ParentNodeType2 NodeAttribute2 = 1>
            <node name = "n3" nodeID = 3>
        </ParentNodeType2>
    </ParentNodeType1>
    <ParentNodeType1 NodeAttribute1 = 2> 
        <ParentNodeType2 NodeAttribute2 = 3>
            <node name = "n4" nodeID=4>
        </ParentNodeType2>
        <ParentNodeType2 NodeAttribute2 = 4>
            <node name = "n5" nodeID=5>
            <node name = "n6" nodeID=6>
        </ParentNodeType2>
    </ParentNodeType1>
</NodeTree>

So n1 and n2 are in parent1 but n3 is one level deeper because the second attribute is not null. Anyone have any thoughts on how this might be done using linq or something like that?

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

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

发布评论

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

评论(1

笔芯 2024-11-07 01:43:25

抱歉,我试图理解这一点,但我失败了。

您的数据似乎没有很好地描述(属性是什么?为什么您不希望在 XML 中映射层次结构?ParentNodeType1/2 应该是什么?NodeAttribute2 似乎是父节点 ID,但在XML 节点 n5 和 n6 都位于 下,我不够聪明,无法检测那里的逻辑:)

尽管如此,为了帮助您,这里是我认为有用的,你可以简单地根据你的“要求”调整它,而无需我知道(眨眼)

using System;
using System.Xml.Linq;
using System.Linq;
using System.Collections.Generic;

namespace X 
{ 
    static class Y 
    {
        public static int Main(string[] args)
        {
            var data = new Record[] {
                new Record(1, "n1", 1, null),
                    new Record(2, "n2", 1, null),
                    new Record(3, "n3", 1, 1),
                    new Record(4, "n4", 2, 2),
                    new Record(5, "n5", 2, 3),
                    new Record(6, "n6", 2, 4),
            };

            Func<Record, XElement> subtree;
            subtree = node => new XElement("node", 
                    new XAttribute("name", node.NodeName),
                    new XAttribute("nodeID", node.NodeID),
                    new XAttribute("NodeAttribute1", node.NodeAttribute1),
                    data.ChildrenOf(node.NodeID).Select(subtree));

            XElement xml = new XElement("NodeTree",
                    data.Where(root => root.NodeAttribute2 == null)
                    .Select(subtree));

            Console.WriteLine(xml);
            return 0;
        }

        struct Record
        {
            public readonly int NodeID;
            public readonly string NodeName;
            public readonly int  NodeAttribute1; //level?
            public readonly int? NodeAttribute2; //parent

            internal Record(int id, string name, int at1, int? at2) 
            {
                NodeID = id;
                NodeName = name;
                NodeAttribute1 = at1;
                NodeAttribute2 = at2;
            }
        }

        private static IEnumerable<Record> ChildrenOf(this IEnumerable<Record> data, int? parentId)
        {
            return data.Where(child => child.NodeAttribute2 == parentId);
        }
    }
}

哦,以防万一,这是输出

<NodeTree>
  <node name="n1" nodeID="1" NodeAttribute1="1">
    <node name="n3" nodeID="3" NodeAttribute1="1">
      <node name="n5" nodeID="5" NodeAttribute1="2" />
    </node>
  </node>
  <node name="n2" nodeID="2" NodeAttribute1="1">
    <node name="n4" nodeID="4" NodeAttribute1="2">
      <node name="n6" nodeID="6" NodeAttribute1="2" />
    </node>
  </node>
</NodeTree>

Sorry, I tried to make sense of this, but I failed.

Your data seems not described very well (what are the attributes? Why don't you want the hierarchy mapped in XML? What are ParentNodeType1/2 supposed to be? NodeAttribute2 appears to be the parent-node-ID, yet in the XML nodes n5 and n6 are both under <ParentNodeType2 NodeAttribute2 = 4> I wasn't smart enough to detect the logic there :)

In an attempt to help you nonetheless, here is what I think would be useful, and you can simply adapt it to your 'requirements' without me having to know about it (wink wink)

using System;
using System.Xml.Linq;
using System.Linq;
using System.Collections.Generic;

namespace X 
{ 
    static class Y 
    {
        public static int Main(string[] args)
        {
            var data = new Record[] {
                new Record(1, "n1", 1, null),
                    new Record(2, "n2", 1, null),
                    new Record(3, "n3", 1, 1),
                    new Record(4, "n4", 2, 2),
                    new Record(5, "n5", 2, 3),
                    new Record(6, "n6", 2, 4),
            };

            Func<Record, XElement> subtree;
            subtree = node => new XElement("node", 
                    new XAttribute("name", node.NodeName),
                    new XAttribute("nodeID", node.NodeID),
                    new XAttribute("NodeAttribute1", node.NodeAttribute1),
                    data.ChildrenOf(node.NodeID).Select(subtree));

            XElement xml = new XElement("NodeTree",
                    data.Where(root => root.NodeAttribute2 == null)
                    .Select(subtree));

            Console.WriteLine(xml);
            return 0;
        }

        struct Record
        {
            public readonly int NodeID;
            public readonly string NodeName;
            public readonly int  NodeAttribute1; //level?
            public readonly int? NodeAttribute2; //parent

            internal Record(int id, string name, int at1, int? at2) 
            {
                NodeID = id;
                NodeName = name;
                NodeAttribute1 = at1;
                NodeAttribute2 = at2;
            }
        }

        private static IEnumerable<Record> ChildrenOf(this IEnumerable<Record> data, int? parentId)
        {
            return data.Where(child => child.NodeAttribute2 == parentId);
        }
    }
}

Oh just in case, here is the output

<NodeTree>
  <node name="n1" nodeID="1" NodeAttribute1="1">
    <node name="n3" nodeID="3" NodeAttribute1="1">
      <node name="n5" nodeID="5" NodeAttribute1="2" />
    </node>
  </node>
  <node name="n2" nodeID="2" NodeAttribute1="1">
    <node name="n4" nodeID="4" NodeAttribute1="2">
      <node name="n6" nodeID="6" NodeAttribute1="2" />
    </node>
  </node>
</NodeTree>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文