C# XML反序列化:将对象存储为单独的XML,还是作为一个XML?

C# XML反序列化:将对象存储为单独的XML,还是作为一个XML?,c#,xml,serialization,C#,Xml,Serialization,我在网上看到很多例子,其中我们有一个带有静态工厂模型反序列化器的类,如下所示。关于此模型的几个问题: 这些示例真的假设我们将每个person实例存储为一个单独的XML文件吗 更常见的情况是,我的XML有一个名为的根元素,然后有许多的集合 在这种情况下,下面的反序列化方法实际上无法正常工作?它似乎构建为只读取一个级别的XML class Person { public Name {get; set;} public Age {get; set;} public stati

我在网上看到很多例子,其中我们有一个带有静态工厂模型反序列化器的类,如下所示。关于此模型的几个问题:

  • 这些示例真的假设我们将每个person实例存储为一个单独的XML文件吗
  • 更常见的情况是,我的XML有一个名为
    的根元素,然后有许多
    的集合
  • 在这种情况下,下面的反序列化方法实际上无法正常工作?它似乎构建为只读取一个级别的XML

    class Person {
        public Name {get; set;}
        public Age {get; set;}
    
        public static Skill Deserialize(string path)
        {
            using (var memoryStream = new StreamReader(path))
            {
                var serializer = new XmlSerializer(typeof(Skill));
                var local = (Skill)serializer.Deserialize(memoryStream);
                local.PostCreateLogic();
                return local;
            }
        }
    
        private void PostCreateLogic()
        {
            Age = Age + 10;
        }
    }
    

  • 谢谢你帮助我更好地理解这一点。一定有什么我看不清楚的地方,因为几乎每个示例都在逐个对象的基础上处理反序列化…

    我的解决方案如下。

    我发现了一些例子,它们将许多人、汽车、技能或对象存储在一个XML文件中。您所要做的就是将工厂模型静态方法放在一个可以调用SkillCollection的类中(例如)。请参见下面的示例:

    [XmlRootAttribute("Skills")]
    public class SkillCollection
    {
        //Not neccessary to use attributes if the Property name matches the XML element name
        [XmlElement(ElementName = "Fire")]
        public Skill Fire { get; [UsedImplicitly] set; }
    
        [XmlElement(ElementName = "Ice")]
        public Skill Ice { get; [UsedImplicitly] set; }
    
        //If all the skills were named the same I could deserialize into an array, as shown below
        //But then I would have no way to access each skill, in my code
        //[XmlArray]
        //public Skill[] SkillCollection { get; set; }
    
        //Factory-Model to create an instance of SkillCollection class
        public static object XmlSerializer_Deserialize(string path, Type toType)
        {
            var deserializer = new XmlSerializer(toType);
            using (TextReader reader = new StreamReader(path))
            {
                object s2 = deserializer.Deserialize(reader);
                if (s2 == null)
                    Console.WriteLine(@"  Deserialized object is null");
                else
                    Console.WriteLine(@"  Deserialized type: {0}", s2.GetType());
                return s2;
            }
        }
    }
    
    和技能等级:

    public class Skill
    {
        [XmlElement(ElementName = "Cast")]
        public int Cast { get; set; }
    
        [XmlElement(ElementName = "ReCast")]
        public int ReCast { get; set; }
    
        [XmlElement(ElementName = "MPCost")]
        public int MpCost { get; set; }
    }
    
    使用以下方法:
    (SkillCollection)SkillCollection.XmlSerializer_反序列化(Path.Combine(Path,“Skills.xml”)、typeof(SkillCollection))并将其存储在可在整个应用程序中访问的属性中

    另外,不要忘记在Skill and SkillCollection中未在XML中定义的任何属性上面使用
    [XmlIgnore]
    。XmlSerializer要求XML元素匹配您试图反序列化到的类中的所有公共属性

    作为旁注,XML不需要按字母顺序排序,如果改用DataContractSerializer,这恰好是一个要求

    希望这对未来的游客有所帮助。有任何问题,请告诉我