“俄罗斯套娃”类 - 读写 XML

Posted

技术标签:

【中文标题】“俄罗斯套娃”类 - 读写 XML【英文标题】:"Matryoshka" Class - Reading and Writing to XML 【发布时间】:2020-07-01 03:57:33 【问题描述】:

所以,我最近有机会使用一种技术,由于没有更好的术语,我将其称为“Matroyshka Class”,以俄罗斯嵌套娃娃命名。该类有一个 List 属性,其中包含同一类的实例,每个实例也有一个类似的列表,或多或少是任意的“深度”。

下面是一个简化的示例:

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

无论如何。我碰到了一点墙。我需要能够读取并将它们写入 XML 文件(或一些类似的外部文件,我想),因为我的程序最终将涉及其中的 lot;将它们放入代码本身似乎是不明智的。编写应该相对简单,使用类似于示例的 ToString() 方法的技术。但是,由于任意的“深度”,我缺乏事后阅读它们的想法。

【问题讨论】:

您能否澄清一下serialize to XML 或其他格式(如 [json](***.com/questions/7895105/…) 时遇到的具体问题?不清楚为什么“任意深度”是序列化的问题...... 因为我不知道序列化是什么-w- XML 对我来说仍然是一个相对较新的工具... 【参考方案1】:

System.Xml.Serialization 命名空间中有您需要的一切。以下是您的俄罗斯套娃类的外观示例(只需进行一些小的更改):

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml.Serialization;

public class Doll  //must be public

    public string Color  get; set; 
    public List<Doll> ChildDolls  get; set;  = new List<Doll>();

    public Doll() //needs a ctor without parameters
    
        Color = "Not set";
    

    public Doll(string color)
    
        this.Color = color;
     // End of Constructor

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

    public override string ToString()
    
        var output = new StringBuilder();

        // Adds the current doll's color
        output.AppendLine(Color);

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

 // End of class

这里是序列化/反序列化方法:

    public static void Serialize(string path, Doll matryoshka)
    
        using (var writer = new StreamWriter(path))
        
            var s = new XmlSerializer(typeof(Doll));
            s.Serialize(writer, matryoshka);
        
    

    public static Doll Deserialize(string path)
    
        using (var reader = new StreamReader(path))
        
            var x = new XmlSerializer(typeof(Doll));
            return (Doll)x.Deserialize(reader);
        
    

使用它们非常简单:

        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>

反序列化也可以正常工作:

        var deserializedDoll = Deserialize("dolls.xml");
        Console.Write(deserializedDoll.ToString());

正如预期的那样,输出是:

red
green1
blue1
green2
blue2

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

【讨论】:

更新:实际上效果很好,谢谢!

以上是关于“俄罗斯套娃”类 - 读写 XML的主要内容,如果未能解决你的问题,请参考以下文章

俄罗斯套娃的选购秘籍

俄罗斯套娃(俄罗斯传统工艺品)详细资料大全

俄罗斯套娃信封问题

LeetCode——俄罗斯套娃信封问题

LeetCode 354. 俄罗斯套娃信封问题

602. 俄罗斯套娃信封