XML序列化导致重复的节点

Hot*_*otN 5 .net c# xml-serialization

我有一个对象结构,我正在尝试序列化为xml,导致重复的节点级别.我很确定它与子类化有关,因为我必须实现自己的反序列化,但我不确定在另一个方向上究竟发生了什么.在应用程序启动时反序列化我的数据时,将相同的xml结构用作输入,就像将其重新序列化以便稍后保存一样.

这是错误输出xml的样子:

<Keyboarding xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Exercises>
    <Exercise>
      <Exercise Id="3" ActivityNumber="5" SubActivityNumber="b" Type="Standard">
        <Title>Test Title</Title>
        <Instructions>Downloaded Update Instructions</Instructions>
      </Exercise>
    </Exercise>
  </Exercises>
</Keyboarding>
Run Code Online (Sandbox Code Playgroud)

这是它应该是什么样子(并且在初始反序列化时看起来像):

<Keyboarding xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Exercises>
      <Exercise Id="3" ActivityNumber="5" SubActivityNumber="b" Type="Standard">
        <Title>Test Title</Title>
        <Instructions>Downloaded Update Instructions</Instructions>
      </Exercise>
  </Exercises>
</Keyboarding>
Run Code Online (Sandbox Code Playgroud)

根对象包含一组练习.Exercise是我的基类,而子类由Type属性决定.我正在使用自定义xml序列化程序来构建来自Exercise的各种派生类型的对象,因为它允许我使用反射来匹配2个左右的潜在派生类型中的任何一个,这些类型在首次读入时处于未知的顺序和数量通过我的申请.

这是使用自定义xml序列化程序的根元素集合:

[XmlArray("Exercises")]
[XmlArrayItem("Exercise", Type = typeof (ExerciseXmlSerializer<Exercise>))]
public Collection<Exercise> UnprocessedExercises { get; set; }
Run Code Online (Sandbox Code Playgroud)

我的基础练习课声明如下:

[Serializable]
[XmlType(AnonymousType = true)]
public class Exercise
Run Code Online (Sandbox Code Playgroud)

我的派生类声明如下:

[Serializable]
[XmlType(AnonymousType = true)]
[XmlRoot(ElementName = "Exercise", IsNullable = false)]
public class StandardExercise : Exercise
Run Code Online (Sandbox Code Playgroud)

这是我的自定义xml序列化程序的编写器部分:

public class ExerciseXmlSerializer<T> : IXmlSerializable where T : class
{
    private T _data;
    ...
    public void WriteXml(XmlWriter writer)
    {
        Type type = _data.GetType();

        new XmlSerializer(type).Serialize(writer, _data);
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

在WriteXml()方法中,类型变量被正确设置为派生类型,那么为什么它为基类型和派生类型创建节点级别?我该如何阻止它这样做?

com*_*ech 1

我认为你的问题在于这一行:

[XmlArrayItem("Exercise", Type = typeof (ExerciseXmlSerializer<Exercise>))]
Run Code Online (Sandbox Code Playgroud)

我认为您不想表明项目的类型是序列化程序的类型。如果要实现 IXmlSerialized,则需要在要序列化的类上。

这是我要做的工作:

public class Keyboarding
{
    [XmlArray("Exercises")]
    [XmlArrayItem("Exercise")]
    public Collection<Exercise> UnprocessedExercises { get; set; }

    public Keyboarding()
    {
        UnprocessedExercises = new Collection<Exercise>();
        UnprocessedExercises.Add(new StandardExercise());
    }
}

[XmlInclude(typeof(StandardExercise))]
public class Exercise
{
}
[Serializable]
public class StandardExercise : Exercise
{
}
Run Code Online (Sandbox Code Playgroud)

这会产生类似于以下内容的输出:

<?xml version=\"1.0\"?>
<Keyboarding xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">
  <Exercises>
    <Exercise xsi:type=\"StandardExercise\" />
  </Exercises>
</Keyboarding>
Run Code Online (Sandbox Code Playgroud)

如果您不希望xsi:type包含在输出中,您可以使用此问题的答案。