字典,其中键是路径,获取 XML 树的方法



我有一个字典,其中键是路径,值是字符串

root/A/A1/A1A    value
root/A/A1/A1B    value
root/A/A1/A1C    value
root/A/A2/A2A    value
root/A/A2/A2B    value
root/B/B1/B1A    value

从接收字典的方法中,我想生成如下所示的XML文件:

<root>
    <A>
        <A1>
            <A1A>value</A1A>
            <A1B>value</A1B>
            <A1C>value</A1C>
        </A1>
        <A2>
            <A2A>value</A2A>
            <A2B>value</A2B>
        </A2>
    </A>
    <B>
        <B1>
            <B1A>value</B1A>
        </B1>
    </B>
</root>

您可以使用 Linq 分组来解决此问题

带循环:

static void WithLinqLoop(Dictionary<string, string> dict)
{
    var flats = from kvp in dict
                let arr = kvp.Key.Split('/')
                select new { l0 = arr[0], l1 = arr[1], l2 = arr[2], l3 = arr[3], l4 = kvp.Value };
    var q = from f in flats
            group f by f.l0 into g0
            select new
            {
                el = g0.Key,
                g = from f in g0
                    group f by f.l1 into g1
                    select new
                    {
                        el = g1.Key,
                        g = from f in g1
                            group f by f.l2 into g2
                            select new
                            {
                                el = g2.Key,
                                g = from f in g2
                                    group f by f.l3 into g3
                                    select new
                                    {
                                        el = g3.Key,
                                        val = g3.First().l4
                                    }
                            }
                    }
            };
    using (var sw = new StringWriter())
    {
        using (var xw = new System.Xml.XmlTextWriter(sw) { Formatting = System.Xml.Formatting.Indented })
        {
            foreach (var n in q)
            {
                xw.WriteStartElement(n.el);
                foreach (var n1 in n.g)
                {
                    xw.WriteStartElement(n1.el);
                    foreach (var n2 in n1.g)
                    {
                        xw.WriteStartElement(n2.el);
                        foreach (var n3 in n2.g)
                        {
                            xw.WriteStartElement(n3.el);
                            xw.WriteString(n3.val);
                            xw.WriteEndElement();
                        }
                        xw.WriteEndElement();
                    }
                    xw.WriteEndElement();
                }
                xw.WriteEndElement();
            }
        }
        var xml = sw.ToString();
        Console.WriteLine(xml);
    }
}

使用递归:

static void WithLinqRec(Dictionary<string, string> dict)
{
    var flats = from kvp in dict
                let arr = kvp.Key.Split('/')
                select new { l0 = arr[0], l1 = arr[1], l2 = arr[2], l3 = arr[3], l4 = kvp.Value };
    var q = from f in flats
            group f by f.l0 into g0
            select new
            {
                el = g0.Key,
                g = from f in g0
                    group f by f.l1 into g1
                    select new
                    {
                        el = g1.Key,
                        g = from f in g1
                            group f by f.l2 into g2
                            select new
                            {
                                el = g2.Key,
                                g = from f in g2
                                    group f by f.l3 into g3
                                    select new
                                    {
                                        el = g3.Key,
                                        g = g3.First().l4
                                    }
                            }
                    }
            };
    var sw = new StringWriter();
    var xw = new System.Xml.XmlTextWriter(sw) { Formatting = System.Xml.Formatting.Indented };
    Action<dynamic> writeNode = null;
    writeNode = (n) =>
    {
        xw.WriteStartElement(n.el);
        if (typeof(string) == n.g.GetType())
        {
            xw.WriteString(n.g);
        }
        else
        {
            foreach (var n1 in n.g)
                writeNode(n1);
        }
        xw.WriteEndElement();
    };
    foreach (var n in q)
        writeNode(n);
    var xml = sw.ToString();
    Console.WriteLine(xml);
}

或使用 GroupByMany 扩展 (https://blogs.msdn.microsoft.com/mitsu/2007/12/21/playing-with-linq-grouping-groupbymany/(

static void WithGroupByManyRec(Dictionary<string, string> dict)
{
    var flats = from kvp in dict
                let arr = kvp.Key.Split('/')
                select new { l0 = arr[0], l1 = arr[1], l2 = arr[2], l3 = arr[3], l4 = kvp.Value };
    var grouped = flats.GroupByMany(f => f.l0, f => f.l1, f => f.l2, f => f.l3);
    var sw = new StringWriter();
    var xw = new System.Xml.XmlTextWriter(sw) { Formatting = System.Xml.Formatting.Indented };
    Action<GroupResult> writeNode = null;
    writeNode = (res) =>
    {
        xw.WriteStartElement(res.Key.ToString());
        if (res.SubGroups == null)
        {
            foreach (dynamic v in res.Items)
            {
                xw.WriteString(v.l4.ToString());
            }
        }
        else
        {
            foreach (var n1 in res.SubGroups)
                writeNode(n1);
        }
        xw.WriteEndElement();
    };
    foreach (var n in grouped)
        writeNode(n);
    var xml = sw.ToString();
    Console.WriteLine(xml);
}

相关内容

  • 没有找到相关文章

最新更新