FlashFast FlashFast - 15 days ago 5
C# Question

How to achieve hierarchical serialization to XML in c#?

Attempting to learn and use a bit more about class serialization to XML.
I can do basic serialisation.

In the following case I have a nested class structure and would like to get it output in its implemented hierarchy to a file in XML standard. The same for deserializing if it there are any caveats.
I had a good search but couldn't understand how to do it.

I know some bits below are not 100% safe but I'm more worried about the serialization functionality. The serializer class extends the Serialize() to any of my classes.

Your help is much appreciated.

public class SysConfigs
{
public SysConfigs() { }

public struct DeadVolumes
{
public struct Valve
{
public uint V1; //valve 1 dead volume in uL
public uint V2; //valve 2 deal volume
public uint V3;
public uint V4;
public uint V5p0;
public uint V5p1;
public uint V5p2;
public uint V5p3;
public uint V5p4;
public uint V5p5;
public uint v5p6;
public uint V5p7;
public uint V5p8;
public uint V5p9;
public uint V5p10;
public uint V5p11;
public uint V5p12;
public uint V5p13;
public uint V5p14;
public uint V6;
}

public struct Mixer
{
public uint M1p1;
public uint M1p2;
public uint M1p3;
public uint M2p1;
public uint M2p2;
public uint M2p3;
}
}
}

public static class Serializer
{
public static void Serialize(this Object obj, string filePath)
{
// Creates an instance of the XmlSerializer class;
// specifies the type of object to be deserialized.
XmlSerializer _xml_serializer = new XmlSerializer(obj.GetType());
XmlWriter _xml_textwriter = XmlWriter.Create(filePath);


try
{
_xml_serializer.Serialize(_xml_textwriter, obj);
}
catch (Exception ex)
{
throw ex;
}

_xml_textwriter.Close();

// If the XML document has been altered with unknown
// nodes or attributes, handles them with the
// UnknownNode and UnknownAttribute events.
_xml_serializer.UnknownNode += new XmlNodeEventHandler(serializer_UnknownNode);
_xml_serializer.UnknownAttribute += new XmlAttributeEventHandler(serializer_UnknownAttribute);
}

// this is where I am testing the my serialization implementation from
private void button1_Click(object sender, EventArgs e)
{
SysConfigs stuff = new SysConfigs();
stuff.Serialize("myfile.xml");
}


The example above produces an XML without contents - that is understood.

<?xml version="1.0" encoding="utf-8"?><SysConfigs xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />


I would like to understand what is required, given the example above, to achieve the following XML program output:

<SysConfigs>
<DeadVolumes>
<Valve>
<V1>123</V1>
<V2>123</V2>
<V3>123</V3>
..etc..
</Valve>
<Mixer>
<M1p1>1</M1p1>
<M1p2>1</M1p2>
<M1p3>1</M1p3>
..etc..
</Mixer>
</DeadVolumes>
</SysConfigs>

Answer

The problem is that your SysConfigs class has no members. So there's nothing to serialize. There's also no need to make the structs nested, or to use structs in the first place. So instead just create a series of classes:

public class Valve
{
    public uint V1;
    // ...
    public uint V6;
}

public class Mixer
{
    public uint M1p1;
    // ...
    public uint M1p3;
}

Then create the container class containing the proper members:

public class DeadVolume
{
    public Valve Valve { get;set; }
    public Mixer Mixer { get;set; }
}

Then add a property to the SysConfigs class:

public class SysConfigs
{
    public DeadVolume DeadVolumes { get; set; }
}

Now you can instantiate and populate a SysConfigs instance and serialize it:

var config = new SysConfigs
{
    DeadVolumes = new DeadVolume
    {
        Valve = new Valve
        {
            V1 = 42,
            // ...
        },
        Mixer = new Mixer
        {
            M1p1 = 43,
            // ..
        }
    }
};