#pragma strict
import System.Xml; // for XmlDocument
function Start()
{
var doc : XmlDocument = new XmlDocument();
doc.Load( Application.dataPath + "/monsters.xml" );
var root : XmlNode = doc.DocumentElement;
Debug.Log( root.Name ); // Here is MyClass (MonsterCollection)
var nodeList : XmlNodeList; // who knows what this does
nodeList = root.SelectNodes( "Monsters" ); // this filters out MySubClass (sub-class Monsters)
// if I have other sub-classes, I can filter them by whatever they're called (eg MySubClass2)
nodeList = nodeList[0].ChildNodes; // this creates a list of all MyObjects within MySubClass
Debug.Log( nodeList.Count ); // this shows I have 2 objects within MySubClass (called Monster)
// loop through each of MyObjects
for ( var i : int = 0; i < nodeList.Count; i ++ )
{
Debug.Log( nodeList[i].Attributes["name"].Value ); // This Shows MyObject[i] key (name = "foo")
// Now how do I get the value of each MySubElement under MyObject[i] ????
//Debug.Log( nodeList[i].Attributes.Element["Health"].Value ); // MySubElement1
//Debug.Log( nodeList[i].Attributes.Element["Attack"].Value ); // MySubElement2
//Debug.Log( nodeList[i].Attributes.Element["Defense"].Value ); // MySubElement3
}
}
As stated in the comment, how do I read and store the value in each sub-element within a MyObject that is found by a specified key?
Thank you for all your help, that has indeed solved the problem on this question.
I just need to understand what the handles are to move around an xml file and extract the information in various layers. Not long ago I learned HashTables, and I thought this would be just as fun, turned out to be very confusing. Like I said on UA, I will still learn all about xml, I’ve put too much time in to give up now. Thanks again, you’ve been a great help.
using System.Xml.Serialization;
public class MonsterCollection
{
public Monster[] Monsters;
}
public class Monster
{
[XmlAttribute("name")]
public string Name;
public int Health;
public int Attack;
public int Defense;
}
FileStream fs = new FileStream("data.xml", FileMode.Open);
MonsterCollection monsters;
XmlSerializer serial = new XmlSerializer(typeof(MonsterCollection));
monsters = serial.Deserialize(fs);
This DANGIT!!!
I can’t for the life of me understand why anyone would use the horribly clunky XMLDoc stuff. Using the XMLSerializer makes it so incredibly easy to read and write .net objects.
At the end, the read example uses a type/class that doesn’t exist, and there are no examples on how to extract the data once the xml has been deserialized.
If you don’t want to read the whole question, here are some highlights :
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?
how can that wiki entry be of any use to a newcomer using xml when it’s open-ended and doesn’t work?
It would have been great if the author of that wiki actually showed how to filter out and loop through the attributes, then gather the subchild nested elements. Basically people who know how to use xml wouldn’t need that wiki, and people like me (with no clue) are left in the dark, totally useless.
Translation of the code posted by KelsoMRK to uJS is quite easy. One difference might be related to uJS convention used in Unity - variable names are camelcase, so they won’t map directly to the elements in sample file. That’s why I added a few additional attributes:
class MonsterCollection
{
@XmlArray("Monsters")
var monsters : Monster[];
}
class Monster
{
@XmlAttribute("name")
var name : String;
@XmlElement("Health")
var health : int;
@XmlElement("Attack")
var attack : int;
@XmlElement("Defense")
var defense : int;
}
var fs : FileStream = new FileStream(pathToFile, FileMode.Open);
var s : XmlSerializer = new XmlSerializer(typeof(MonsterCollection));
var collection : MonsterCollection;
collection = s.Deserialize(fs) as MonsterCollection;
fs.Dispose();
and iterating through monsters:
for (monster in collection.monsters)
{
Debug.Log(monster.name);
Debug.Log(monster.health);
Debug.Log(monster.attack);
Debug.Log(monster.defense);
}
Thanks for that ArkaneX. The last comment was just a quick one before I walked out the door, and was more about how cranky I still am about the wiki tutorial being so incomplete (rather than the helpful comment that was left byKelsoMRK was in C#). Thanks to everyone who commented here.
Now that you’ve fixed the error in my question with the deserializer, am going to start looking at how I can extract data from the collection like the above examples and your comment on my question :
Anyway - now you have your monster collection filled with your dragon data from file. And they’re already standard .NET classes, not XML data any more, so you can iterate using for or foreach, you can use LINQ, etc
Thank you all for your time and patience dealing with someone who is self-taught and has no experience in xml.
This seems like a great way of working with XML, but unless I’m misunderstanding your example this is for creating xml attributes. How can you relate this to reading and using data from files?
Please take a look at the second code fragment from my last post. Data that is used to create instance of a MonsterCollection class (through deserialization) is read from file, with help of a FileStream.