XML Serialization Custom Class array

Hi Guys,

I can’t seem to get an answer to this. Even though people have had similar problems, I just don’t understand the response.

I would like to serialize my class and write it out in XML to be able to save and load data at a later stage. I am writing just simple stuff out like positions and names at the moment.

Here is a my code.

import System;
import System.Xml;
import System.Xml.Serialization;
import System.IO;
import System.Text;

class XMLWriter
{
	var x : float;
	var y : float;
	var z : float;
	var name : String;
	private var _data : String = "";
	private var _FileLocation : String;
	private var myData : UserData; 

	
	function Save(fileloc : String, objects : Array)
	{
	myData=new UserData();
	var counter = 0;
		for(obj in objects)
		{
		//Debug.Log(obj.transform.name);
		// mydata is an instance of UserData class, _iUser.x is a variable of that class that implements DemoData
		//myData._iUser.x = obj.transform.position.x;
		//myData._iUser.y = obj.transform.position.y;
		//myData._iUser.z = obj.transform.position.z;
		//myData._iUser.name = obj.transform.name;
		myData.CommitModifications(
		obj.transform.position.x,
		obj.transform.position.y,
		obj.transform.position.z,
		obj.transform.name
		);
		//_data = SerializeObject(myData);
		counter ++;
		}
		_data = SerializeObject(myData);
		_FileLocation = fileloc;
		CreateXML();
	}
	// save and load methods for the file itself
	function CreateXML()
	{
	   var writer : StreamWriter;
	   //FileInfo t = new FileInfo(_FileLocation+"\\"+ _FileName);
	   var t : FileInfo = new FileInfo(_FileLocation);
	   if(!t.Exists)
	   {
	      writer = t.CreateText();
	   }
	   else
	   {
	      t.Delete();
	      writer = t.CreateText();
	   }
	   writer.Write(_data);
	   writer.Close();
	   Debug.Log("File written.");
	}
	 
	function LoadXML()
	{
	   //StreamReader r = File.OpenText(_FileLocation+"\\"+ _FileName);
	   var r : StreamReader = File.OpenText(_FileLocation);
	   var _info : String = r.ReadToEnd();
	   r.Close();
	   _data=_info;
	   Debug.Log("File Read");
	}
	function SerializeObject(pObject : Object) // serializing enable the conversion of XML documents and streams to common language runtime objects and vice versa.
	{
	   var XmlizedString : String  = null;
	   var memoryStream : MemoryStream  = new MemoryStream();
	   var xs : XmlSerializer = new XmlSerializer(typeof(UserData));
	   var xmlTextWriter : System.Xml.XmlTextWriter  = new System.Xml.XmlTextWriter(memoryStream, Encoding.UTF8);
	   xs.Serialize(xmlTextWriter, pObject);
	   memoryStream = xmlTextWriter.BaseStream; // (MemoryStream)
	   XmlizedString = UTF8ByteArrayToString(memoryStream.ToArray());
	   return XmlizedString;
	}
	
	/* The following methods came from the referenced URL */
//string UTF8ByteArrayToString(byte[] characters)
	function UTF8ByteArrayToString(characters : byte[] )
	{     
   		var encoding : UTF8Encoding  = new UTF8Encoding();
   		var constructedString : String  = encoding.GetString(characters);
   		return (constructedString);
	}
 
	//byte[] StringToUTF8ByteArray(string pXmlString)
	function StringToUTF8ByteArray(pXmlString : String)
	{
   		var encoding : UTF8Encoding  = new UTF8Encoding();
   		var byteArray : byte[]  = encoding.GetBytes(pXmlString);
   		return byteArray;
	}


	class DemoData
	{
		var x : float;
		var y : float;
		var z : float;
		var name : String;
	}
 
// UserData is our custom class that holds our defined objects we want to store in XML format
 	class UserData
 	{
    	// We have to define a default instance of the structure
   		public var _iUser : DemoData = new DemoData();
    	public var SceneData = new Array();
    	// Default constructor doesn't really do anything at the moment
   		function UserData() { }
   		function CommitModifications(x : float, y : float, z : float, name : String)
   		{
   		var _iUserClone : DemoData = new DemoData();
   		_iUserClone.x = x;
   		_iUserClone.y = y;
   		_iUserClone.z = z;
   		_iUserClone.name = name;
   		SceneData.Push(_iUserClone);
   		}
	}


}

Now, that works fine, but I am getting item information on top, which I do not want. Refer to picture 3.
I simply want the data between

I know why it’s happening, it’s because the line in picture 2. However when I comment that out, I Get the error (Just under picture 2.). - The type of the argument object ‘XMLWriter.DemoData’ is not primitive.

The original version is the code you are seeing above, picture 1.

Can anyone explain why if I remove this line I get this error? But otherwise it works? It makes no sense to me. Also possibly how to solve it?

Figured it out.

I still don’t comprehend exactly, but the array needs to be declared like so:

// to make it a type Demo Data
public var SceneData = new DemoData[4];

now it seems to work

I don’t seem to understand why don’t you just use reflection?

Something like

PropertyInfo[] myPropertyInfo;
Component l_temp;
		
myPropertyInfo = l_temp.GetType().GetProperties(BindingFlags.Public|BindingFlags.Instance);
		
for (int i = 0; i < myPropertyInfo.Length; i++)
{		   
if(myPropertyInfo[i].CanRead&myPropertyInfo[i].CanWrite)
	{
        object propretyValue = myPropertyInfo[i].GetValue(l_temp,null);
         //now just serialize your proprety name and value to xml and use reflection to deserialize as well :)
        }
}

Well it’s really simple.

Because I had no idea about reflection.

I am self taught scripter. But now that you told me about it, I would look into it.

Buy siaqodb, much simpler :slight_smile: