【问题标题】:Parse XML file nodes and store it to a Dictionary解析 XML 文件节点并将其存储到字典
【发布时间】:2019-08-12 09:33:14
【问题描述】:
<?xml version="1.0" encoding="utf-8" ?>
<LanguagePacks>
  <Language name = "EN">
    <item key="play" value="play"/>
    <item key="pause" value="pause"/>
    <item key="resume" value="resume"/>
    <item key="all" value="all"/>
    <item key="songs" value="songs"/>
    <item key="song" value="song"/>
    <item key="skip" value="skip"/>
    <item key="next" value="next"/>
    <item key="previous" value="previous"/>
    <item key="number" value="number"/>
    <item key="album" value="album"/>
  </Language>
  <Language name = "DE">
    <item key="play" value="spiel"/>
    <item key="pause" value="pause"/>
    <item key="resume" value="resume"/>
    <item key="all" value="alle"/>
    <item key="songs" value="lieder"/>
    <item key="song" value="lied"/>
    <item key="skip" value="skipp"/>
    <item key="next" value="nachste"/>
    <item key="previous" value="vorheriger"/>
    <item key="number" value="nummer"/>
    <item key="album" value="alben"/>
  </Language>
</LanguagePacks>

我想解析上述 xml 文件中的 Language name == "EN" 并将键值对存储在字典中。我在下面尝试的代码..但错误显示已添加具有相同键的项目。请帮忙。

 XDocument doc = XDocument.Load($"{path}");
    var output = doc.Element("LanguagePacks")
        .Descendants().Where(r=>(string)r.Attribute("name").Value == "EN")
        .Descendants()
        .ToDictionary(k => k.Name, v => v.Value);

【问题讨论】:

  • 您肯定不想要LanguagePacks 的后代的后代。我认为您可以删除第二个Descendants-call。否则你肯定有两个items 命名为play,例如。
  • 尝试以下操作: Dictionary output = doc.Descendants("Language").Where(x => (string)x.Attribute("name") == "EN") .FirstOrDefault().Elements("item") .GroupBy(x => (string)x.Attribute("key"), y => (string)y.Attribute("value")) .ToDictionary(x => x.Key, y => y.FirstOrDefault());

标签: c# xml linq dictionary


【解决方案1】:
.ToDictionary(k => k.Name, v => v.Value);

k 是一个item,如果你想要你的Dictionary 喜欢

[0] = {[play, play]}
[1] = {[pause, pause]}

我认为对于每个item,您访问属性以获取值

var output = doc.Element("LanguagePacks")
        .Descendants().Where(r=>(string)r.Attribute("name").Value == "EN")
        .Descendants() // list of item
        .ToDictionary(k => k.Attribute("key").Value, v => k.Attribute("value").Value);

【讨论】:

    【解决方案2】:

    ToDictionary(k =&gt; k.Name, v =&gt; v.Value) 不会按照您想要的方式工作,因为 NameValue 属性是节点名称 (item) 和节点内容 (无),而不是 xml 属性 "key" 和 @987654326 @。

    当您实际上只想循环遍历一层元素时,也不应该使用Descendants。 在示例 XML 上运行代码会产生 NullReferenceException,因为 &lt;LanguagePacks&gt; 的某些后代没有 name 属性,而您假设它们都有。

    这段代码应该做你想做的事。请注意,如果您有重复的键,或者 &lt;item /&gt; 元素缺少键或值属性,这也会崩溃。

    doc.Element("LanguagePacks")
        .Elements("Language")
        .Where(x => x.Attribute("name")?.Value == "EN")
        .Elements("item")
        .ToDictionary(x => x.Attribute("key").Value, x => x.Attribute("value").Value)
        .Dump();
    

    【讨论】:

      【解决方案3】:

      .ToDictionary(k => k.Name, v => v.Value);
      

      k.Name 将始终为 item,而不是 key="..." 的值。

      我猜v.Value 将永远是"",不完全确定。

      【讨论】:

      • 解决办法是什么?这个答案没有多大帮助。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多