【问题标题】:How do I load multiple XML nodes with two attributes as key-value pairs?如何加载具有两个属性作为键值对的多个 XML 节点?
【发布时间】:2017-11-06 10:51:44
【问题描述】:

我有一个这样的 XML 文件;

<?xml version="1.0" encoding="utf-8"?>
<Data>
  <StringMaps>
    <Menu>
      <String Target="BtnFile" Link="Файл" />
      <String Target="BtnOpen" Link="Открыто" />
      <String Target="BtnSave" Link="Сохранить" />
      <String Target="BtnClose" Link="Закрыть" />
    </Menu>
  </StringMaps>
</Data>

然后我使用 XmlDocument 加载文档。

然后我有两个XmlNodeList,它们是targetAttrslinkAttrs

我正在使用此代码来获取值;

        var targetAttrs = xmldoc1.SelectNodes("/Data/StringMaps/Menu/String/@Target");
        var linkAttrs = xmldoc1.SelectNodes("/Data/StringMaps/Menu/String/@Link");
        foreach (XmlNode temptarget in targetAttrs)
        {
            foreach (XmlNode templink in linkAttrs)
            {
                MessageBox.Show(string.Format("{0} = {1}", temptarget.Value, templink.Value));
            }
        }

我正在尝试获取像这样的键值对的值;

BtnFile = Файл
BtnOpen = Открыто
BtnSave = Сохранить
BtnClose = Закрыть

但我得到了这些;

BtnFile = Файл
BtnFile = Открыто
BtnFile = Сохранить
BtnFile = Закрыть
BtnOpen = Файл
BtnOpen = Открыто
BtnOpen = Сохранить
BtnOpen = Закрыть
BtnSave = Файл
BtnSave = Открыто
BtnSave = Сохранить
BtnSave = Закрыть
BtnClose = Файл
BtnClose = Открыто
BtnClose = Сохранить
BtnClose = Закрыть

如果有人编写代码并解释确切的逻辑,我将不胜感激。

【问题讨论】:

    标签: c# xml foreach xml-attribute


    【解决方案1】:

    使用 xml linq:

    using System.Collections.ObjectModel;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml;
    using System.Xml.Linq;
    
    
    namespace ConsoleApplication57
    {
        class Program
        {
            const string FILENAME = @"c:\temp\test.xml";
            static void Main(string[] args)
            {
                XDocument doc = XDocument.Load(FILENAME);
                Dictionary<string,string> dict = doc.Descendants("String")
                    .GroupBy(x => (string)x.Attribute("Target"), y => (string)y.Attribute("Link"))
                    .ToDictionary(x => x.Key, y => y.FirstOrDefault());
            }
    
    
        }
    
    }
    

    【讨论】:

      【解决方案2】:

      我建议使用XmlDocument 的替代方法:使用linq XDocument 并将其转换为Dictionary

      var xml = @"<?xml version=""1.0"" encoding=""utf-8""?>
      <Data>
       <StringMaps>
        <Menu>
         <String Target=""BtnFile"" Link=""Файл"" />
         <String Target=""BtnOpen"" Link=""Открыто"" />
         <String Target=""BtnSave"" Link=""Сохранить"" />
         <String Target=""BtnClose"" Link=""Закрыть"" />
        </Menu>
       </StringMaps>
      </Data>";
      
      XDocument xdoc = XDocument.Parse(xml);
      
      var dict = xdoc
          .Descendants("String")
          .ToDictionary(n => n.Attribute("Target").Value, n => n.Attribute("Link").Value);
      
      foreach (var keyValuePair in dict) 
      {
          MessageBox.Show($"{keyValuePair.Key} = {keyValuePair.Value}"); 
      }
      

      【讨论】:

      • 前两个答案是我一直在寻找的,但是您和 jdweng 的答案是阅读/解析 xml 文档的不错选择。感谢您的宝贵时间!
      【解决方案3】:

      你想要的属性属于同一个 XMLNode。 您的外部循环找到元素。 然后你的内部循环寻找相同的节点来显示第二个属性。

      搜索节点一次并显示两个属性。

              var MenuItems =xmldoc1.SelectNodes("/Data/StringMaps/Menu/String");
      
              foreach(XmlNode MenuItem in MenuItems)
              {
                   MessageBox.Show(string.Format("{0} ={1}",MenuItem.Attributes["Target"].Value, MenuItem.Attributes["Link"].Value));
      
              }
      

      【讨论】:

        【解决方案4】:
        var strings = xmldoc1.SelectNodes("/Data/StringMaps/Menu/String");
        foreach (var node in strings)
        {
            MessageBox.Show($"{node.Attributes["Target"].Value} = {node.Attributes["Link"].Value}");
        }
        

        【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-04-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多