C#中的多维关联数组

时间:2012-02-09 02:28:21

标签: c# xml arrays

我对C#完全陌生。我是一名PHP程序员。所以请耐心等待。

我有一个XML,其中包含以下内容:

<setting name="event1" color="white" align="center" />
<setting name="event2" color="red" align="left" />

我已经知道如何使用XmlReader GetAttribute获取信息,但我完全不知道如何将它存储到数组中。我想拥有的最终数组将是这样的:

Array
(
    [event1] => Array
    (
        [color] => white
        [align] => center
    )
    [event2] => Array
    (
        [color] => red
        [align] => left
    )
)

因此,如果我想从名为“settings”的数组中访问信息,我会使用:

settings["event1"]["color"] = "white";

我如何在C#中做这样的事情?请记住,我对C#完全陌生。

-----编辑

我尝试过添加一个类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace xSplit_Panel_Writer
{
    class Settings
    {
        public string Color { get; set; }
        public string Align { get; set; }
    }
}

但是我在实际脚本中遇到问题......

        using (XmlReader reader = XmlReader.Create("data/config.xml"))
        {
            while (reader.Read())
            {
                if ((reader.NodeType == XmlNodeType.Element) && (reader.Name == "setting"))
                {
                    var settings = new Dictionary<string, Settings>();
                    settings.Add(reader.Name, reader);
                }
            }
        }

我收到以下错误:

Error   1   The best overloaded method match for 'System.Collections.Generic.Dictionary<string,xSplit_Panel_Writer.Settings>.Add(string, xSplit_Panel_Writer.Settings)' has some invalid arguments  C:\Users\Jaxel\documents\visual studio 2010\Projects\xSplit Panel Writer\xSplit Panel Writer\MainForm.cs    31  25  xSplit Panel Writer
Error   2   Argument 2: cannot convert from 'System.Xml.XmlReader' to 'xSplit_Panel_Writer.Settings'    C:\Users\Jaxel\documents\visual studio 2010\Projects\xSplit Panel Writer\xSplit Panel Writer\MainForm.cs    31  51  xSplit Panel Writer

3 个答案:

答案 0 :(得分:5)

如果XML中的属性是静态的,我会选择创建一个类来封装您的数据。这将为您提供一个强类型对象,其中包含您可以编写代码的属性,获得完整的编译时支持,智能感知等。

class Setting
{
    public string Name { get; set; }
    public string Color { get; set; }
    public string Align { get; set; }
}

然后,您可以使用您的数据填充此类的实例,创建它们的列表,甚至可以使用Name作为键将它们加载到字典中。

var setting = LoadSettingFromXml();
var settings = new Dictionary<string, Setting>();
settings.Add(setting.Name, setting); 

// elsewhere
settings["event1"].Color = "blue";

您可以从那里了解如何使用Linq-to-Xml将XML读入这些对象,并进一步了解您喜欢的集合类型。


一个完整的代码示例。给定上面定义的类和有效的XML片段

string xml = @" <settings>
                    <setting name=""event1"" color=""white"" align=""center"" /> 
                    <setting name=""event2"" color=""red"" align=""left"" />
                </settings>";

您可以使用Linq-to-Xml将文档解析为一系列对象。

// can also use XDocument.Load(...) to load from a file or stream.
var document = System.Xml.Linq.XDocument.Parse(xml);
var settingsList = (from element in document.Root.Elements("setting")
                    select new Setting
                    {
                        Name = element.Attribute("name").Value,
                        Color = element.Attribute("color").Value,
                        Align = element.Attribute("align").Value
                    }).ToList();

您可以将其进一步转换为字典。首先,显示使用循环创建字典“漫长的路”。

var settingsDictionary = new Dictionary<string, Setting>();
foreach (var setting in settingsList)
{
    settingsDictionary.Add(setting.Name, setting);
}

但你也可以使用Linq将序列转换为没有显式循环的字典。

var settingsDictionary = settingsList.ToDictionary(s => s.Name, s => s);

作为参考,Linq代码需要.NET 3.5+(C#3.0 +,Visual Studio 2008+版本),并引用System.Core.dll,System.Xml.Linq.dll,并使用System.Linq的指令和System.Xml.Linq。默认情况下,在Visual Studio中创建的大多数新解决方案中都会引用DLL。

答案 1 :(得分:0)

您需要嵌套的Dictionary个实例:

var outer = new Dictionary<String, Dictionary<String, String>>();
var inner = new Dictionary<String, String>();
inner["align"] = "left";
// ...
outer["Event1"] = inner;

答案 2 :(得分:0)

如果您使用XDocument代替XmlReader,我认为您会更好。这样,您可以加载XML,然后立即以您想要的方式立即访问它:

XElement settingsParent = …;

var event1Color = settingsParent.Elements()
                                .Single(s => s.Attribute("name").Value == "event1")
                                .Attribute("color").Value;

当然,它比使用关联数组的代码更冗长,但另一方面,您不必编写任何转换代码。