[Mono-devel-list] XML (de)serialization

Herscovici, Avi AHerscovici at Empirix.com
Tue Jun 24 11:03:52 EDT 2003


First project with mono/mcs and I've run into a couple problems.  I'm
getting incorrect output from (XML) deserializing when attributes are used.
Serializing with attributes gives the same xml file as .net produces, but
when deserializing, I get values from the default constructor and not the
ones I assigned to the members of the object before I serialized it.  This
works fine if I don't have any attributes (such as [XMLAttribute]).  Also,
trying to serialize an inherited class causes an unhandled
NullReferenceException to be thrown.  Can someone fill me in as to the
status of xml serializing and deserializing?  I am willing to contribute as
this is critical to my project (more critical is deserializing XML in mono
that is already serialized in .Net (windows)).  Below are code examples for
which I obtain errors and the errors:  (All of this is compiled with MCS
0.24 and run with mono 0.24)

-Avi

//------------------- serial-test.cs
----------------------------------------

// Test what objects mono can serialize and De-serialize.
using System;
using System.Xml.Serialization;
using System.IO;
using System.Xml;
using Test;


namespace Serial.test {

public class sertest {

		public static void Save(System.IO.Stream stream, object x)
		{
			XmlSerializer ser = new
XmlSerializer(typeof(Script));
			ser.Serialize(stream, x);
		}

		public static void Save(string filename, object x)
		{
			FileStream str = new FileStream(filename,
FileMode.Create, FileAccess.Write);
			Save(str, x);
			str.Close();
		}

		public static object Load(System.IO.Stream stream)
		{
			object s;
			Console.WriteLine("Debug line 1a");
			XmlSerializer ser = new
XmlSerializer(typeof(Script));
			Console.WriteLine("Debug line 2a");
		//	try {
			s = (object)ser.Deserialize(stream);
		//	}
		//	catch (Exception e) {Console.WriteLine("Exception: "
+ e);}
		//	s = null;
			return s;
		}


		public static object Load(string filename)
		{
				object s;
				Console.WriteLine("Debug line 2");
				FileStream str = new FileStream(filename,
FileMode.Open, FileAccess.Read);
				Console.WriteLine("Debug line 3");
				s = Load(str);
				Console.WriteLine("Debug line 4");
				str.Close();
				return s;
		}

	static void Main() {

	string filename = "test.ser";

	Script x =  new Script();

	x.X=0;
	x.Y=1;
	x.Z=2;
	x.String="TEST";
	x.Foo= new Bar();
	x.Foo.I=10;

	Save(filename, x);

	Script temp = (Script)Load(filename);

	Console.WriteLine("The values are: ");
	Console.WriteLine(temp.X);
	Console.WriteLine(temp.Y);
	Console.WriteLine(temp.Z);
	Console.WriteLine(temp.String);
	Console.WriteLine(temp.Foo.I);



	}

}

}

// ------------------------ test.cs -----------------------------

namespace Test
{
	[XmlRoot(ElementName="Script", Namespace="http://www.foo.com")]
	public class Script
	{
		// Vars
		private int m_x;
		private int m_y;
		private int m_z;
		private string m_str;
		private Foo m_foo;

		// Constructor
		public Script()
		{
		m_x = -3;
		m_y = -2;
		m_z = -1;
		m_str = null;
		m_foo = null;
		}

		// Properties
		[XmlIgnore()]
		public int X
		{
			get { return m_x; }
			set { m_x = value; }
		}

		[XmlAttribute("y")]
		public int Y
		{
			get { return m_y; }
			set { m_y = value; }
		}

		[XmlAttribute("z")]
		public int Z
		{
			get { return m_z; }
			set { m_z = value; }
		}

		[XmlAttribute("str")]
		public string String
		{
			get { return m_str; }
			set { m_str = value; }
		}
	

		public Foo Foo
		{
			get { return m_foo; }
			set { m_foo = value; }
		}
	}
	

	[XmlInclude(typeof(Bar))]
	public class Foo
	{
		private int m_i;
		public int I
		{
			get { return m_i; }
			set { m_i = value; }
		}
	}

	[XmlRoot("Bar", Namespace="http://www.foo.com")]
	public class Bar : Foo
	{
		private int m_j;
		public int J
		{
			get { return m_j; }
			set { m_j = value; }
		}
	}

}

//------------------------------------------------- OUTPUT
----------------------------------------

output that I get when I run this in .Net:
Debug line 2
Debug line 3
Debug line 1a
Debug line 2a
Debug line 4
The values are:
-3
1
2
TEST
10

(which is correct, x.X has an ignore attribute)

under linux:
Unhandled Exception: System.NullReferenceException: A null value was found
where an object instance was required
in <0x00236> 00 System.Xml.Serialization.XmlSerializer:SerializeMembers
(System.Xml.XmlWriter,object,bool)
in <0x00795> 00 System.Xml.Serialization.XmlSerializer:WriteElement
(System.Xml.XmlWriter,System.Xml.Serialization.XmlAttributes,string,string,S
ystem.Type,object)
in <0x00eb1> 00 System.Xml.Serialization.XmlSerializer:SerializeMembers
(System.Xml.XmlWriter,object,bool)
in <0x00a02> 00 System.Xml.Serialization.XmlSerializer:Serialize
(System.Xml.XmlWriter,object,System.Xml.Serialization.XmlSerializerNamespace
s)
in <0x00071> 00 System.Xml.Serialization.XmlSerializer:Serialize
(System.IO.Stream,object)
in <0x00049> 00 Serial.test.sertest:Save (System.IO.Stream,object)
in <0x0004a> 00 Serial.test.sertest:Save (string,object)
in <0x00101> 00 Serial.test.sertest:Main ()


(concerning the incorrect output with attributes)
Now, if i comment out everything that has to do w/ Foo and Bar here is what
I get:
Debug line 2
Debug line 3
Debug line 1a
Debug line 2a
Debug line 4
The values are: 
-3
-2
-1

(incorrect)

If I keep that commented out and also comment out all the attributes I get:
Debug line 2
Debug line 3
Debug line 1a
Debug line 2a
Debug line 4
The values are: 
0
1
2
TEST

(which is the correct result)...



More information about the Mono-devel-list mailing list