1

我正在序列化一个具有基类型的右属性的类。

[Serializable]    
public class MyClass{
    public BaseChild Left {get;set;}
    public BaseChild Right {get;set;}
}

如果我序列化它,我会得到一个类似这样的 xml:

<Left p7:type="InherrittedChild" xmlns:p7=blabla>
   <Property />
</Left>

我可以在这些属性上设置一些选项以使 xml 看起来像这样:

<Left>
   <InherittedChild>
       <Property />
   </InherittedChild>
</Left>

因为我有两个相同类型的属性,所以我不能只添加,[XmlInclude(typeof(child))]因为这会呈现一个模棱两可的 xml。

4

1 回答 1

1

真的很棘手... XmlSerialization 不是多态的,因此您的 XML 通常会提供对象层次结构的扁平化版本。我看到了两种可能的实现。第一个将基本属性公开为另一个名称(请参阅“ConcreteChild”)。另一个实现 IXmlSerialization(请参阅“ConcreteChild2”),以便您可以编写自定义的属性嵌套。

// Base Class
[Serializable]
[XmlInclude(typeof(ConcreteChild))]
public class BaseChild
{
    public BaseChild()
    {
        ChildName = "Base";
    }

    public String ChildName { get; set; }
}

// Exposing Parent Property
[Serializable]
public class ConcreteChild : BaseChild
{
    public new String ChildName { get; set; }

    public String BaseChildName { 
        get
        {
            return ((BaseChild) this).ChildName;
        }

        set
        {
            ((BaseChild)this).ChildName = value;
        }
    }
}


// Writing Custung Serializable
[Serializable]
public class ConcreteChild2 : BaseChild, IXmlSerializable
{
    public new String ChildName { get; set; }

    public System.Xml.Schema.XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(XmlReader reader)
    {
    }

    public void WriteXml(XmlWriter writer)
    {
        writer.WriteStartElement("InherittedChild");
        writer.WriteElementString("ConcreteChildName", ChildName);
        writer.WriteEndElement();

        // Since BaseChild does not implement IXmlSerializable
        // we cannot use base.WriteXml(writer);
        writer.WriteElementString("BaseChildName", ((BaseChild) this).ChildName);
    }
}

[XmlInclude(typeof(ConcreteChild))]
[XmlInclude(typeof(ConcreteChild2))]
[Serializable]
public class MyClass
{
    public BaseChild Left { get; set; }

    [XmlElement("ConcreteChild2", typeof(ConcreteChild2))]  // does not work without !!!
    public BaseChild Right { get; set; }

}

结果:您可以在 MyClass 结构中看到两个序列化

<?xml version="1.0" encoding="utf-16"?>
<MyClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Left xsi:type="ConcreteChild">
    <ChildName>Left</ChildName>
    <BaseChildName>Base</BaseChildName>
  </Left>
  <ConcreteChild2>
    <InherittedChild>
      <ConcreteChildName>Right</ConcreteChildName>
    </InherittedChild>
    <BaseChildName>Base</BaseChildName>
  </ConcreteChild2>
</MyClass>

序列化

var mc = new MyClass();
mc.Left = new ConcreteChild { ChildName = "Left"};
mc.Right = new ConcreteChild2 { ChildName = "Right" };
StringWriter textWriter = new StringWriter();
XmlSerializer xmlSerializer = new XmlSerializer(mc.GetType());
xmlSerializer.Serialize(textWriter, mc);
var s = textWriter.ToString();
于 2013-07-31T08:51:49.627 回答