【问题标题】:Dictionary where the key is the path, method to get an XML tree?字典的关键是路径,获取XML树的方法?
【发布时间】:2018-08-20 04:50:11
【问题描述】:

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

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>

【问题讨论】:

  • 请出示您编写的代码。另请访问help center 并阅读How to Ask 以了解如何使用该网站。
  • @JimGarrison 我应该显示什么代码?我需要帮助来做一个将字典转换为 XML 文件的方法,它应该适用于这种类型的所有字典。我的代码在这种情况下不相关。

标签: c# xml dictionary path


【解决方案1】:

你可以使用 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);
}

【讨论】:

  • 谢谢你,@Tom!这很有帮助!
  • 不客气。这是一个很好的问题,我很喜欢解决它:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-02-11
  • 2018-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-09
相关资源
最近更新 更多