【问题标题】:How to debug XML deserialization?如何调试 XML 反序列化?
【发布时间】:2014-11-15 15:47:01
【问题描述】:

我想知道您是否对如何调试以下 XML 反序列化有任何提示?我无法让它工作。反序列化器基本上创建了召唤和斜线实例,但它们的所有属性都是空的。相关类如下所示。


带有反序列化器的 SkillCollection 类:

[DataContract(Name = "Skills", Namespace = "")]
public class SkillCollection
{

[DataMember(Name = "Slash")]
public Skill Slash { get; set; }

[DataMember(Name = "Summon")]
public Skill Summon { get; set; }

public static object Deser(string path, Type toType)
{
    var s = new DataContractSerializer(toType);
    using (FileStream fs = File.Open(path, FileMode.Open))
    {
        object s2 = s.ReadObject(fs);
        if (s2 == null)
            Console.WriteLine(@"  Deserialized object is null");
        else
            Console.WriteLine(@"  Deserialized type: {0}", s2.GetType());
        return s2;
    }
}

通过属性Skills从另一个类调用:

Skills = (SkillCollection)SkillCollection.Deser(
            Path.Combine(path, "Skills.xml"), 
            typeof(SkillCollection));

技能等级:

public class Skill
{
    //Cast: time it takes to cast it
    [DataMember(Name = "Cast")]
    public float Cast { get; set; }

    //ReCast: cooldown period before player can cast it again
    [DataMember(Name = "ReCast")]
    public float ReCast { get; set; }

    [DataMember(Name = "MPCost")]
    public int MpCost { get; set; }

    public Timer Timer { get; private set; }
    public bool Ready { get; set; }

    public Skill()
    {
        Ready = true;

        Timer = new Timer { Interval = ReCast + 500, AutoReset = false };
        Timer.Elapsed += OnTimedEvent;
    }

    //Runs when recast is up
    private void OnTimedEvent(object source, ElapsedEventArgs e)
    {
        Ready = true;
    }
}

XML 文件:

<Skills>
  <Slash>
    <Cast>0.00</Cast>
    <ReCast>60.00</ReCast>
    <MPCost>0</MPCost>
  </Slash>
  <Summon>
    <Cast>5.98</Cast>
    <ReCast>2.49</ReCast>
    <MPCost>0</MPCost>
  </Summon>
</Skills>

为了避免混淆,我的目标是运行反序列化程序,然后让 SkillCollection 类包含 Skill 的两个实例(Slash 和 Summon),并能够通过它们的属性分别访问它们。

感谢您提供有关调试此问题的任何帮助/提示。

【问题讨论】:

  • 附加问题:1) 属性的顺序是否必须与 XML 中的顺序相匹配? 2) 如果 XML 中没有所有块的属性怎么办(比如 XML 有第三种技能叫做 kick,但 kick 在 SkillCollection 中没有属性)。这会引起问题吗? 3) 反过来呢(有些属性在 XML 中没有与之匹配的块)。那会是个问题吗?谢谢
  • 我认为调试的第一步是通过序列化程序运行您的对象并查看它生成的 XML。然后您可以将它与您提供的 XML 进行比较。但是,DataContractSerializer 不是我的选择。它有很多陷阱,例如it requires the properties to be in alphabetical order in the xml。请改用XmlSerializer
  • @mikez 谢谢!!按 alpha 排序并使用 Magnus 提供的代码对问题进行排序。谢谢你们!
  • @mikez 我使用 DataContractSerializer 的原因是我可以将我的属性设置器保密。我发现这很有帮助:web.archive.org/web/20130430190551/http://www.danrigsby.com/…

标签: c# xml serialization xml-deserialization


【解决方案1】:

安德斯,

我最近做了一个类似的任务。查看您的代码,您似乎将 DataContract Name 和 Namespace 设置错了。在 Skill 类和 SkillCollection 类上方都需要指定:[DataContract(Name = "Skills", Namespace = "")]。这对于“允许”序列化程序进入属性至关重要。请记住,仅将其设置在 SkillCollection 类之上是不够的。

编辑:我最初以为你可以省略 Namespace,但你不能。它必须设置为Namespace="",如果您没有在 XML 中指定命名空间,或者设置为任何您指定的命名空间,如果您指定了它。

另外,调试它的一种方法是将 Deser 方法更改为:

    public static object Deserialize(string path, Type toType)
    {
        using (var sr = new FileStream(path, FileMode.Open))
        {
            SkillCollection p = null;
            XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(sr, new XmlDictionaryReaderQuotas());
            var serializer = new DataContractSerializer(toType);

            while (reader.Read())
            {
                switch (reader.NodeType)
                {
                    case XmlNodeType.Element:
                        if (serializer.IsStartObject(reader))
                        {
                            Console.WriteLine(@"Found the element");
                            p = (SkillCollection)serializer.ReadObject(reader);
                            Console.WriteLine("{0} {1}    id:{2}",
                                p.Slash.ToString(), p.Summon.ToString());
                        }
                        Console.WriteLine(reader.Name);
                        break;
                }
            }

            return p;
        }
    }

【讨论】:

  • 感谢您的编辑。我尝试按照最初的建议省略命名空间,但使用您建议的调试代码很明显需要包含它。
猜你喜欢
  • 2019-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-08
相关资源
最近更新 更多