Create an xml node tree from a result set but combining repeated attributes using linq or expressions
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" n开发者_如何学CodeID=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?
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>
精彩评论