C# &引用;Matryoshka“;类-读取和写入XML

C# &引用;Matryoshka“;类-读取和写入XML,c#,xml,class,xmlreader,C#,Xml,Class,Xmlreader,因此,我最近有机会使用一种技术,由于没有更好的术语,我以俄罗斯嵌套娃娃的名字命名为“Matroyshka类”。该类有一个列表属性,该属性包含相同类的实例,每个实例都有一个类似的列表,或多或少具有任意的“深度” 下面是一个简化的示例,它可能看起来像什么: class Doll { public string Color; public List<Doll> ChildDolls; // End of properties. Getters and Setters

因此,我最近有机会使用一种技术,由于没有更好的术语,我以俄罗斯嵌套娃娃的名字命名为“Matroyshka类”。该类有一个列表属性,该属性包含相同类的实例,每个实例都有一个类似的列表,或多或少具有任意的“深度”

下面是一个简化的示例,它可能看起来像什么:

class Doll
{
    public string Color;
    public List<Doll> ChildDolls;
    // End of properties. Getters and Setters not included for readability.

    public Doll(string color)
    {
        this.Color = color;
        this.ChildDolls = new List<Doll>();
    } // End of Constructor

    public void AddChild(Doll NewChild)
    {
        this.ChildDolls.Add(NewChild);
    } // End of Add Child method

    public override string ToString()
    {
        string output;

        // Adds the current doll's color
        output += this.Color + "\n";

        // Adds each doll's children, and each of theirs, and so on...
        foreach (Doll Child in this.ChildDolls)
        {
            output += Child.ToString();
        }
        return output;
    } // End of To String method

} // End of class
类玩偶
{
公共字符串颜色;
公开名单娃娃;
//属性结束。为了可读性,不包括getter和setter。
公共玩偶(字符串颜色)
{
这个。颜色=颜色;
this.ChildDolls=新列表();
}//构造函数的结尾
公共void AddChild(Doll NewChild)
{
this.ChildDolls.Add(NewChild);
}//添加子方法的结尾
公共重写字符串ToString()
{
字符串输出;
//添加当前玩偶的颜色
输出+=此.Color+“\n”;
//添加每个玩偶的孩子和他们的孩子,依此类推。。。
foreach(此中的娃娃儿童。娃娃娃娃)
{
output+=Child.ToString();
}
返回输出;
}//结束到字符串的方法
}//下课

无论如何。我碰到了一堵墙。我需要能够读写XML文件(或者类似的外部文件,我想),因为我的程序最终会涉及很多这样的文件;将它们放入代码本身似乎是不明智的。编写应该相对简单,使用与示例的ToString()方法类似的技术。然而,由于任意的“深度”,我缺乏事后阅读它们的想法。
System.Xml.Serialization
命名空间中有您需要的一切。下面是一个Matryoshka类的示例(只需要一些小的更改):

使用它们非常简单:

        var redDoll = new Doll("red");

        var green1Doll = new Doll("green1");
        var green2Doll = new Doll("green2");

        var blue1Doll = new Doll("blue1");
        var blue2Doll = new Doll("blue2");

        redDoll.AddChild(green1Doll);
        redDoll.AddChild(green2Doll);

        green1Doll.AddChild(blue1Doll);

        green2Doll.AddChild(blue2Doll);

        Serialize("dolls.xml", redDoll);
结果如下:

<?xml version="1.0" encoding="utf-8"?>
<Doll xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Color>red</Color>
  <ChildDolls>
    <Doll>
      <Color>green1</Color>
      <ChildDolls>
        <Doll>
          <Color>blue1</Color>
          <ChildDolls />
        </Doll>
      </ChildDolls>
    </Doll>
    <Doll>
      <Color>green2</Color>
      <ChildDolls>
        <Doll>
          <Color>blue2</Color>
          <ChildDolls />
        </Doll>
      </ChildDolls>
    </Doll>
  </ChildDolls>
</Doll>
正如预期的那样,输出为:

red
green1
blue1
green2
blue2

您还可以使用属性控制序列化程序如何生成XML。以下是

您能澄清一下在使用[json]()或其他格式时遇到的具体问题吗?不太清楚为什么“任意深度”是序列化的一个问题…因为我不知道序列化是什么-w-XML对我来说仍然是一个相对较新的工具…更新:事实上效果很好,谢谢!
<?xml version="1.0" encoding="utf-8"?>
<Doll xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Color>red</Color>
  <ChildDolls>
    <Doll>
      <Color>green1</Color>
      <ChildDolls>
        <Doll>
          <Color>blue1</Color>
          <ChildDolls />
        </Doll>
      </ChildDolls>
    </Doll>
    <Doll>
      <Color>green2</Color>
      <ChildDolls>
        <Doll>
          <Color>blue2</Color>
          <ChildDolls />
        </Doll>
      </ChildDolls>
    </Doll>
  </ChildDolls>
</Doll>
        var deserializedDoll = Deserialize("dolls.xml");
        Console.Write(deserializedDoll.ToString());
red
green1
blue1
green2
blue2