【问题标题】:An Array of Dictionary in C# - Possible?C# 中的字典数组 - 可能吗?
【发布时间】:2010-10-20 02:44:00
【问题描述】:

我可以使用字典对象数组吗?

我有一个想要修改的 XML。我要使用的数据结构是这样的 -

Dictionary<element, Dictionary<attr, value>>

element - 是我要修改的元素 attr - 我要更新其值的属性 value - 我要更新的值

<Parents>
    <Parent id="ParentA" description="New">
        <Children>
            <Child name="ChildA" />
        </Children>
    </Parent>
</Parents>

我想通过以下

Dictionary<string, string> dict_Attributes1=new Dictionary<string, string>();
Dictionary<string, string> dict_Attributes2=new Dictionary<string, string>();
dict_Attributes1.Add("id", "ParentB");
dict_Attributes1.Add("description", "Old");
dict_Attributes2.Add("name", "ChildB");
Dictionary<string, Dictionary<string, string>> dict_Elements = new Dictionary<string, Dictionary<string, string>>();
dict_Elements.Add(".", dict_Attributes1);//To update the Element
dict_Elements.Add("Children/Child", dict_Attributes2);//To update the Children's Attributes

假设我已经确定我要更新 id 为 ParentA 的 Parent。

现在,我在这里创建 dict_Attributes1、dict_Attributes2 等,有没有办法可以将它们存储在一个(动态,编译时大小未知)字典对象数组中?

或者,有没有更好的方法来做到这一点 - 1.修改Selected XElement及其子属性的属性?

编辑

<?xml version="1.0" encoding="utf-8"?>
<Configuration>
    <Environments>
        <Environment id="Master" description="MasterSystem">
            <Systems>
                <DefaultSystem systemName="Master" server="http://localhost" />
            </Systems>
        </Environment>
    </Environments>
</Configuration>

现在,当用户更改 id 和描述时,我想用新值更新这个 XML 文件。在更改 id 和描述(从用户那里获得)时,我想用相同的 id 值更新 systemName。

如果新的id是“Development”,description是“DevelopmentSystem”,

输出的 XML 应该是

<?xml version="1.0" encoding="utf-8"?>
<Configuration>
    <Environments>
        <Environment id="Development" description="DeveloperSystem">
            <Systems>
                <DefaultSystem systemName="Development" server="http://localhost" />
            </Systems>
        </Environment>
    </Environments>
</Configuration>

【问题讨论】:

  • 只需使用List&lt;Dictionary&lt;string, string&gt;&gt;
  • @Kanini:有几件事 - 您可以使用 XSLT 来执行此操作,而不是尝试实现您自己的通用方式来指定应如何更新文件。除此之外,我建议专门编写代码来处理这种情况,而不是期望您的代码的用户构造一个带有选项路径的字典。更好的是,使用 XML 序列化,让他们编辑类的属性,而不是关心数据是如何存储的。
  • @Kanini:别误会,新值的 XPath 字典是一个有趣的选择,但是有更简单(编码和使用)且不易出错的编程方式这个。
  • @Kanini:使用 XSLT(如 Merlyn 所说)或 Linq-to-XML 会好得多
  • @Kanini:support.microsoft.com/kb/307322w3schools.com/xsl。顺便说一句,w3schools 非常适合 HTML/XML 参考和教程 :)

标签: c# arrays dictionary


【解决方案1】:

是的,这是可能的。我不确定你需要哪一个,但它们都使用List&lt;T&gt;

var list = new List<Dictionary<string, string>>();

或者:

var list = new List<Dictionary<string, Dictionary<string, string>>>();

【讨论】:

    【解决方案2】:

    虽然你想做的事是允许的,但我个人会使用LINQ to XML

    有一点学习曲线,但是如果您至少熟悉 LINQ 和 XML,那么在玩过一点之后就会有意义。它可能比您建议的结构更有效,而且肯定会更容易适应和维护(由您,尤其是由其他人),因为它们是一种标准化技术。

    【讨论】:

      【解决方案3】:

      有比数组更好的选择,它会按照我认为你想要的方式运行:

      var dictionaries = new List<Dictionary<string, string>>();
      

      这是可动态调整大小的,无需将内容重新复制到新数组。与向字典中添加新条目的方式类似,您可以向列表中添加新条目:

      var dict = new Dictionary<string, string> { { "Key1", "Value1" }, };
      dictionaries.Add(dict);
      

      至于你问的具体问题:

      现在,我在这里创建 dict_Attributes1、dict_Attributes2 等,有没有办法可以将它们存储在一个(动态,编译时大小未知)字典对象数组中?

      是的,您可以创建字典对象的数组。这与您在代码顶部指定的字典字典不同,并且不容易调整大小(尽管可以在运行时指定大小,您可以通过创建一个新数组并复制来“调整”它的大小)旧数组的内容)。

      字典数组如下所示:

      var dictionaries = new Dictionary<string, string>[0];
      

      如果要在运行时指定大小,只需将[0] 替换为变量即可。

      【讨论】:

      • 梅林:谢谢。但是怎么做?我做了谷歌(然后是必应)搜索,但无济于事。一个代码示例,一个代码示例的链接……什么都可以。
      【解决方案4】:

      您可以尝试使用ArrayList&lt;Dictionary&lt;string,string&gt;&gt;

      ArrayList 的行为类似于数组,但可以动态添加。

      或者,查看System.Xml.Linq 中可用的类

      【讨论】:

        【解决方案5】:

        如果这样做的目的是编辑 XML 文件,那么您使用的工具有误。我强烈建议使用 Linq to XML。这是一个非常简单的示例,说明如何使用 Linq 修改 XML 文件。

        using System.Xml.Linq;
        //starting with the XML you provided:
        /*
        <Parents>
            <Parent id="ParentA" description="New">
                <Children>
                    <Child name="ChildA" />
                </Children>
            </Parent>
        </Parents>
        */
        
        XDocument xdoc = XDocument.Load(@"\path\to\xml\file");
        
        // get the first <child> element (the long way)
        XElement xeParents = xdoc.Descendants("Parents").FirstOrDefault();
        XElement xeParent = xeParents.Descendants("Parent").FirstOrDefault();
        XElement xeChildren = xeParent.Descendants("Children").FirstOrDefault();
        XElement xeChild = xeChildren.Descendants("Child").FirstOrDefault();
        
        //Change the value of an attribute
        xeParent.SetAttributeValue("id", "ParentB");
        
        //let's add another child for fun
        XElement xeChild2 = new XElement("Child");
        xeChild2.SetAttributeValue("name", "ChildB");
        xeChildren.Add(xeChild2);
        
        xdoc.Save(@"\path\to\save\file");
        
        
        
        //a shorter way to get the first <Child> would be:
        xeChild = xdoc.Descendants("Child").FirstOrDefault();
        
        //now the XML would look like this: 
        /*      
        <Parents>
            <Parent id="ParentB" description="New">
                <Children>
                    <Child name="ChildA" />
                    <Child name="ChildB" />
                </Children>
            </Parent>
        </Parents>
        */
        

        【讨论】:

        • jb:谢谢!但是,如果我想在一个函数中执行此 ModifyXML 操作,我将要更新的元素、属性/值对的列表、我要更新的子元素(以及属性/值对的列表)和 XML 传递给该函数怎么办?我输入的是 3 三个不同的文件?
        • 那么我必须给出一个全新的答案:)
        • 如果这需要进一步解释,请告诉我。我会使用这个命令: xeElement.Descendants("childname").Where(xe => xe.Attribute("attrname") != null).ToList().ForEach(xe => xe.SetAttributeValue("attrname" , "属性值"));
        猜你喜欢
        • 2014-04-25
        • 1970-01-01
        • 2021-07-09
        • 2013-04-14
        • 2012-03-07
        • 1970-01-01
        • 1970-01-01
        • 2016-07-15
        • 1970-01-01
        相关资源
        最近更新 更多