Search code examples
c#xml-deserialization

XMLSerializer finds unknown nodes


I have a XML File that I want to deserialize into a C# class.

The XML file looks like this:

<?xml version="1.0" ?>
<Animation name="Scene1">
<Object name="Object1">
    <Polygons>
        <Polygon vert0="1" vert1="2" vert2="0"/>
        <Polygon vert0="1" vert1="3" vert2="2"/>
    </Polygons>
    <Transform>
        <Frame Idx="1">
            <Location x="50.0" y="50.0" z="0.0"/>
            <Rotation x="0.0" y="0.0" z="0.0"/>
            <Scaling x="40.0" y="40.0" z="1.0"/>
        </Frame>
        <Frame Idx="60">
            <Location x="500.0" y="220.0" z="0.0"/>
            <Rotation x="0.0" y="0.0" z="0.0"/>
            <Scaling x="40.0" y="40.0" z="1.0"/>
        </Frame>
    </Transform>
</Object>
</Animation>

For the C# Classes I have the following to represent the animation:

[Serializable]
public class Animation
{
    [XmlAttribute("name")]
    public string Name { get; set; }

    [XmlArray("Object")]
    public Object[] Objects { get; set; }

    public static Animation AnimationFactory(string filename)
    {
        XmlSerializer serializer = new XmlSerializer(typeof(Animation));
        serializer.UnknownNode += new XmlNodeEventHandler(serializer_UnknownNode);
        serializer.UnknownAttribute += new XmlAttributeEventHandler(serializer_UnknownAttribute);

        FileStream fs = new FileStream(filename, FileMode.Open);

        return (Animation)serializer.Deserialize(fs);
    }

    private static void serializer_UnknownNode(object sender, XmlNodeEventArgs e)
    {
        Console.WriteLine("Unknown Node: " + e.Name);
    }

    private static void serializer_UnknownAttribute
    (object sender, XmlAttributeEventArgs e)
    {
        Console.WriteLine("Unknown Attribute: " + e.Attr.Name);
    }
}

For the Object:

[Serializable]
public class Object
{
    [XmlAttribute("name")]
    public string Name { get; set; }

    [XmlElement("Polygons")]
    public Polygons Polygons { get; set; }

    [XmlElement("Transform")]
    public Transform Transforms { get; set; }
}

For the Transforms:

[Serializable]
public class Transform
{
    [XmlArray("Frame")]
    public FrameTRS[] Frames { get; set; }
}

The FrameTRS looks like this:

[Serializable]
[XmlInclude(typeof(Frame))]
public class FrameTRS : Frame
{
    [XmlElement]
    public Location Location { get; set; }

    [XmlElement]
    public Rotation Rotation { get; set; }

    [XmlElement]
    public Scaling Scaling { get; set; }
}

[Serializable]
public class Frame
{
    [XmlAttribute("Idx")]
    public int Index;
}

Whereas each location, Scaling, Rotation derives from:

[Serializable]
[XmlInclude(typeof(Coordinates))]
public class Rotation : Coordinates
{
}

[Serializable]
public class Coordinates
{
    [XmlAttribute("x")]
    public double X { get; set; }

    [XmlAttribute("y")]
    public double Y { get; set; }

    [XmlAttribute("z")]
    public double Z { get; set; }
 }

And for the Polygons I have:

[Serializable]
public class Polygons
{
    [XmlArray("Polygon")]
    public Polygon[] Polygon { get; set; }
}

[Serializable]
public class Polygon
{
    [XmlAttribute("vert0")]
    public int Vert0 { get; set; }

    [XmlAttribute("vert1")]
    public int Vert1 { get; set; }

    [XmlAttribute("vert2")]
    public int Vert2 { get; set; }

    [XmlAttribute("vert3")]
    public int Vert3 { get; set; }
}

When I call the Animation.AnimationFactory("file") I don't get an exception but the Animation Object returned only has the name and an empty Object. And I get this output in the console as it does not recognize the nodes: Unknown Node: Polygons Unknown Node: Transform

Can anyone help me? Thank you!


Solution

  • I found the solution, maybe it will help someone:

    I changed the XmlArray Attributes to XmlElement Attributes, now it works as intended.