【问题标题】:How to get XML into a dictionary in c#如何在 C# 中将 XML 放入字典中
【发布时间】:2014-10-22 12:42:52
【问题描述】:

我有以下 XML:

<Axis>
    <Collections>
        <Collection>
            <Client>
                <Name>Client 1</Name> 
                <Value>345</Value> 
            </Client>
        </Collection>
        <Collection>
            <Client>
                <Name>Client 1</Name> 
                <Value>4532</Value> 
            </Client>
        </Collection>
        <Collection>
            <Client>
                <Name>Client 1</Name> 
                <Value>235</Value> 
            </Client>
        </Collection>
        <Collection>
            <Client>
                <Name>Client 1</Name> 
                <Value>8756</Value> 
            </Client>
        </Collection>
        <Collection>
            <Client>
                <Name>Client 1</Name> 
                <Value>76</Value> 
            </Client>
        </Collection>
    </Collections>
    <Collections>
        <Collection>
            <Client>
                <Name>Client 2</Name> 
                <Value>56</Value> 
            </Client>
        </Collection>
        <Collection>
            <Client>
                <Name>Client 2</Name> 
                <Value>43</Value> 
            </Client>
        </Collection>
        <Collection>
            <Client>
                <Name>Client 2</Name> 
                <Value>34</Value> 
            </Client>
        </Collection>
        <Collection>
            <Client>
                <Name>Client 3</Name> 
                <Value>42</Value> 
            </Client>
        </Collection>
        <Collection>
            <Client>
                <Name>Client 3</Name> 
                <Value>23</Value> 
            </Client>
        </Collection>
    </Collections>
</Axis>

我想将其中的一些存储在字典Dictionary&lt;string, List&lt;string&gt;&gt; 中,其中键是名称元素,值是值元素的列表。

我已经搞砸了一些 LINQ,但我无法计算出字典部分。

我已经能够将一个元素放入列表中:

myDoc.XPathSelectElements("//Axis/Collections/Collection/Client/Value")
     .Select(v => v.Value)
     .ToList();

【问题讨论】:

    标签: c# xml dictionary


    【解决方案1】:

    我建议:

    • 不使用 XPath 来选择元素,而是使用 Elements() 方法(等)
    • 通过ToLookup 使用查找而不是Dictionary&lt;string, List&lt;string&gt;&gt;。查找就像一个字典,每个键有多个值,但处理起来稍微简单一些(因为如果您要求缺少键,它会返回一个空序列)并且更容易构造。

    所以代码看起来像:

    var lookup = doc.Root
                    .Elements("Collections")
                    .Elements("Collection")
                    .Elements("Client")
                    .ToLookup(x => (string) x.Element("Name"),
                              x => (string) x.Element("Value"));
    

    然后您可以执行以下操作:

    foreach (var value in lookup["Client 1"])
    {
        ...
    }
    

    所有Elements() 调用的替代方法是使用Descendants(),例如

    var lookup = doc.Descendants("Client")
                    .ToLookup(x => (string) x.Element("Name"),
                              x => (string) x.Element("Value"));
    

    【讨论】:

      【解决方案2】:

      我建议使用允许查询的构造,我个人最喜欢查询 XML 的是 Linq to XML。

      • 首先,获取您所追求的内容(名称和值)。
      • 然后,按名称分组
      • 最后,投影到您的目标类型(字典)

      示例(您可以将其直接复制并粘贴到 LinqPad 中):

      var xml = @"<Axis>
      <Collections>
         <Collection>
             <Client>
                 <Name>Client 1</Name> 
                 <Value>345</Value> 
             </Client>
         </Collection>
         <Collection>
             <Client>
                 <Name>Client 1</Name> 
                 <Value>4532</Value> 
             </Client>
         </Collection>
         <Collection>
             <Client>
                 <Name>Client 1</Name> 
                 <Value>235</Value> 
             </Client>
         </Collection>
         <Collection>
             <Client>
                 <Name>Client 1</Name> 
                 <Value>8756</Value> 
             </Client>
         </Collection>
         <Collection>
             <Client>
                 <Name>Client 1</Name> 
                 <Value>76</Value> 
             </Client>
         </Collection>
      </Collections>
      <Collections>
         <Collection>
             <Client>
                 <Name>Client 2</Name> 
                 <Value>56</Value> 
             </Client>
         </Collection>
         <Collection>
             <Client>
                 <Name>Client 2</Name> 
                 <Value>43</Value> 
             </Client>
         </Collection>
         <Collection>
             <Client>
                 <Name>Client 2</Name> 
                 <Value>34</Value> 
             </Client>
         </Collection>
         <Collection>
             <Client>
                 <Name>Client 3</Name> 
                 <Value>42</Value> 
             </Client>
         </Collection>
         <Collection>
             <Client>
                 <Name>Client 3</Name> 
                 <Value>23</Value> 
             </Client>
         </Collection>
      </Collections>
      </Axis>";
      
      var doc = XDocument.Parse(xml);
      var dict = (from row in doc.Root.Descendants("Client")
                  let name = row.Element("Name").Value
                  let value = row.Element("Value").Value
                  group value by name into grp
                  select new { grp.Key, Values = grp.ToList() }).ToDictionary(d => d.Key, d => d.Values);
      dict.Dump();
      

      【讨论】:

        【解决方案3】:
        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Text;
        using System.Threading.Tasks;
        using System.Xml.Linq;
        
        namespace XMLToDictionary
        {
            class Program
            {
                static void Main(string[] args)
                {
                    var doc = XDocument.Load("c:\\Test.xml");
        
                    var clients = doc.Descendants().Where(e => e.Name.LocalName == "Client").ToList();
                    Dictionary<string, List<string>> dic = new Dictionary<string, List<string>>();
                    foreach (var client in clients)
                    {
                        string key = client.Elements().First(e => e.Name.LocalName == "Name").Value;
                        string val = client.Elements().First(e => e.Name.LocalName == "Value").Value;
                        if (!dic.ContainsKey(key))
                        {
                            dic[key] = new List<string>();
                        }
                        dic[key].Add(val);
                    }
        
        
                }
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-01-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多