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

时间:2014-09-19 11:19:33

标签: c# xml serialization

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

  1. 这些示例是否真的假设我们将每个人实例存储为一个单独的XML文件?
  2. 更常见的情况是,我的XML有一个名为<Persons>的根元素,然后会有多组<Person>吗?
  3. 在这种情况下,下面的反序列化方法不能正常工作吗?它似乎是为了读取只有一个级别的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;
        }
    }
    
  4. 感谢您帮助我更好地理解这一点。必须有一些我看不到的东西,因为几乎每个例子都是逐个对象地处理反序列化......

1 个答案:

答案 0 :(得分:1)

我的解决方案如下所示。

我在一个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_Deserialize(Path.Combine(path, "Skills.xml"), typeof(SkillCollection));并将其存储在您可以在整个应用程序中访问的属性中...

此外,不要忘记在Skill和SkillCollection中未在XML中定义的任何属性上方使用[XmlIgnore]。 XmlSerializer需要XML元素匹配您尝试反序列化的类中的所有公共属性。

作为旁注,XML不需要按字母顺序排序,如果您使用DataContractSerializer,则恰好需要这样做。

希望这有助于未来的访客。有任何问题,请告诉我。