0

I have an XSD schema including some "simple" parts and more "complex" parts (they can not be serialized the proper way using the framework attributes ). I use the .Net serializer for the simple parts and wrote a custom serializer for the more complex parts, by implementing the IXmlSerializable interface on the inner object.

When I test the code, I get on the output only the "custom" part deserialized (when reading). If I comment the property referencing the complex object on the "root" class, then all the simple serialization happens (read & write). It seams that the handmade serializer takes all the control over the serialization instead of serializing only the inner object as wanted. Up to me this is a strange behavior, so where is the bug??

Is it possible to use the IXmlSerializable on an inner object only?

This is the "root" class :

public class RootElement
{
    [XmlAttribute("foo")]
    public Foo foo;

    [XmlAttribute("bar")]
    public Bar? bar;

    public bool ShouldSerializeBar()
    {
        return bar.ShouldSerialize;
    }

    [XmlElement("SimpleXml")]
    public SimpleXml simpleXml;

    // commenting these two lines radically change the serialization
    [XmlElement("ComplexXmlWithCustomSerializer")]
    public ComplexXml complexXml;
}

End this is the "ComplexXml" class

 public class ComplexXml : IXmlSerializable
{
    public double pty1;

    public double? pty2;

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

    public void ReadXml(XmlReader reader)
    {
        XmlReader reader2 = reader.ReadSubtree();
        while (reader2.Read())
        {
            if (reader2.NodeType == XmlNodeType.Element)
            {
                string unit;
                switch (reader2.Name)
                {
                    case "Pty1":
                        unit = reader2.GetAttribute("unit");
                        if (string.Equals(unit, "mm"))
                            pty1 = double.Parse(reader2.GetAttribute("value"));
                        break;
                    case "Pty2":
                        unit = reader2.GetAttribute("unit");
                        if (string.Equals(unit, "deg"))
                            pty2 = double.Parse(reader2.GetAttribute("value"));
                        break;
                }
            }
            if (reader2.NodeType == XmlNodeType.EndElement)
                reader2.ReadEndElement();
        }
    }

    public void WriteXml(XmlWriter writer)
    {
        //pty1
        writer.WriteStartElement("Pty1");
        writer.WriteAttributeString("unit", "mm");
        writer.WriteAttributeString("value", pty1.ToString());
        writer.WriteEndElement();

        //pty2
        if (pty2.HasValue)
        {
            writer.WriteStartElement("Pty2");
            writer.WriteAttributeString("unit", "deg");
            writer.WriteAttributeString("value", WrapAngle.Value.ToString());
            writer.WriteEndElement();
        }
    }
}
Sylvain B.
  • 719
  • 5
  • 31

1 Answers1

0

I could find an answer to this problem in a similar question here.

The point is to end the ReadXml(XmlReader reader) method with

            reader.Read();

I do not understand precisely why it works, but this line enables the reader to continue the reading of the XML document after the end of the custom method...

Community
  • 1
  • 1
Sylvain B.
  • 719
  • 5
  • 31