How to read data with 'Saving and Loading Data : XmlSerializer'

I’m following the guide on the Unity Wiki : http://wiki.unity3d.com/index.php?title=Saving_and_Loading_Data:_XmlSerializer

I’ve created my monsters.xml, Monster.js and MonsterContainer.js and there are no errors.

Now in my test script :

var dragonName : String = "EarthDragon";
var baseHealth : int = 0;
var baseAttack : int = 0;
var baseDefense : int = 0;

function Start() 
{
	var monsterCollection : MonsterCollection = MonsterContainer.Load( Path.Combine( Application.dataPath, "monsters.xml" ) );
}

this gives the error :

Assets/_Scripts/XmlTest.js(48,33): BCE0018: The name 'MonsterCollection' does not denote a valid type ('not found'). 

Now I understand there is no class named MonsterCollection therefore the type doesn’t exist, but I’m following a ‘tutorial’, I’ve never done this before and frankly don’t know what I’m supposed to do. Is this thing supposed to recognize MonsterCollection as the root element of the xml? Am I missing a class?

My goal is to read an Attribute of the root element by name, then populate my variables based on the values in nested elements under that Attribute. How can I achieve this?

The examples found here are using a completely different method to the wiki. The question here suggests using an available package, but I’m coding in uJS. Can anyone help me with this problem, understand why the guide is failing, and how I can populate my variables based on a name to reference an attribute (child element)? Thanks.


Further information :

monster.xml

<MonsterCollection>
	<Monsters>
		<Monster name="EarthDragon">
			<Health>45</Health>
			<Attack>49</Attack>
			<Defense>49</Defense>
		</Monster>
		<Monster name="FireDragon">
			<Health>39</Health>
			<Attack>52</Attack>
			<Defense>43</Defense>
		</Monster>
	</Monsters>
</MonsterCollection>

Monster.js

import System.Xml;
import System.Xml.Serialization;

public class Monster
{
	@XmlAttribute("name")
	public var name : String;

	public var health : int;
	public var attack : int;
	public var defense : int;
}

MonsterContainer.js

import System.Collections.Generic;
import System.Xml;
import System.IO;

@XmlRoot("MonsterCollection")
public class MonsterContainer
{
	@XmlArray("Monsters")
	@XmlArrayItem("Monster")
	
	public var Monsters : List.< Monster > = new List.< Monster >();

	public function Save( path : String )
	{
		var serializer : XmlSerializer = new XmlSerializer( MonsterContainer );
		var stream : Stream = new FileStream( path, FileMode.Create );
		serializer.Serialize( stream, this );
		stream.Close();
	}

	public static function Load( path : String ) : MonsterContainer 
	{
		var serializer : XmlSerializer = new XmlSerializer( MonsterContainer );
		var stream : Stream = new FileStream( path, FileMode.Open );
		var result : MonsterContainer = serializer.Deserialize( stream ) as MonsterContainer;
		stream.Close();
		
		return result;
	}
	
	//Loads the xml directly from the given string. Useful in combination with www.text.
	public static function LoadFromText( text : String ) : MonsterContainer
	{
		var serializer : XmlSerializer = new XmlSerializer(MonsterContainer);
		return serializer.Deserialize(new StringReader(text)) as MonsterContainer;
	}
}

1 Answer

1

I didn’t test the code, but the line which gives you error is wrong and should be corrected in the wiki. Variable monsterCollection should be of type MonsterContainer instead of MonsterCollection.

In the wiki sample, author remapped a class MonsterContainer to a root XML element named MonsterCollection. After deserialization of this XML, you should have an instance of MonsterContainer class, not MonsterCollection class (because there is no such class). For me, such remapping might be a source of confusion, and I try to avoid this in most cases, especially if I can control the structure of XML.

If this mixing is no problem for you, just leave it as it is. But I would just change MonsterContainer class name to MonsterCollection.

[Second part of the tutorial][1] I linked is more suitable for your case, but anyway - please read both :) [1]: http://www.codeproject.com/Articles/487571/XML-Serialization-and-Deserialization-Part-2