- Home /
Getting data from XML
I've a LevelController script with Serializable Classes containing data required for each level ( see Attached Image) I want to get these data from a nested XML file .
I tried some of the XML parsing however not sure how to get int/float values and I'm not able to format it properly .
Please help me with a c# script to get data from a XML file and assign it in LevelController script
Can you add the try you did in your question? The script and a example xml if possible. Then we can try to fix / improve it.
Answer by chetanisinanand · Mar 24, 2015 at 07:28 PM
Thanks Cherno for your great explanation, However using System.XML will add a couple of MBs to your project, Rather I used Lightweight XML parser and figured out how it works ,
I'm putting here my code if this can help someone out there :-) Just download the XML parser from the link and drag all three file in your Assets directory.
This is my XML file I used for demonstration:
Levels.xml
<LevelsContainer>
<Level id ="1" attribute1 ="5" atribute2 ="avoid red dots">
<NodeA>
<NodeB attributeB1 ="1.2" attributeB2 ="-60">
<NodeC attributeC1 ="1"></NodeC>
</NodeB>
</NodeA>
</Level>
<Level id ="2" attributeA ="5" atributeB ="">
<NodeA>
<NodeB attributeB1 ="1.2" attributeB2 ="60">
<NodeC attributeC1 ="120"></NodeC>
</NodeB>
</NodeA>
</Level>
<LevelsContainer>
And here is the XML Reader Script:
using UnityEngine;
using System.Collections;
public class XMLReaderExample : MonoBehaviour
{
public TextAsset LevelXMLFile ;
// Use this for initialization
void Start (){
XMLParser parser = new XMLParser();
XMLNode LevelXML = parser.Parse(LevelXMLFile.text);
int _numberOfLevels = LevelXML.GetNodeList ("LevelsContainer>0>Level").Count;
for (int i = 0; i < _numberOfLevels; i++) {
string _attribute1ValueString = LevelXML.GetValue ("LevelsContainer>0>Level>" + i + ">@attribute1");
int _attribute1ValueInt;
int.TryParse(_attribute1ValueString,out _attribute1ValueInt);
Debug.Log (_attribute1ValueInt);
//similarly we can get attribute2 Values, or any other attribute from any other node
int _nodeACount = LevelXML.GetNodeList("LevelsContainer>0>Level>" + i + ">NodeA").Count;
for (int j = 0; j < _nodeACount; j++) {
int _nodeBCount = LevelXML.GetNodeList("LevelsContainer>0>Level>" + i + ">NodeA>" +j+ ">NodeB").Count;
for (int k = 0; k < _nodeBCount; k++) {
string _attributeB1ValueString = LevelXML.GetValue ("LevelsContainer>0>Level>" + i + ">NodeA>" +j+ ">NodeB>" +k+ ">@attributeB1");
float _attributeB1ValueFloat;
float.TryParse (_attributeB1ValueString,out _attributeB1ValueFloat);
Debug.Log (_attributeB1ValueFloat);
XMLNode _nodeC = LevelXML.GetNode ("LevelsContainer>0>Level>" + i + ">NodeA>" +j+ ">NodeB>" +k+ ">NodeC>0");
// Do whatever you want with nodeC values :-)
// GetNode("path>0>to>0>array>0>node>0");
// GetNodeList("path>0>to>0>array");
// GetValue("path>0>to>0>array>0>node>0>@attribute");
}
}
}
}
}
Happy Coding :-) Apologies for typing mistakes (if any)
Answer by Cherno · Mar 20, 2015 at 02:25 PM
Ok, here goes. I'm gonna use an example from my own project, a weapons class that is fed via XML file.
I recommend "XML Notepad", and be sure to enode to "utf-8".
Suppose you have the Weapon class:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Xml;
using System.Xml.Serialization;
[System.Serializable]
public class Weapon {
[XmlIgnore]/*[System.NonSerialized]*/ public GameObject muzzleflashObject;
[XmlAttribute("name")] public string name = "";
[XmlAttribute("damage")] public int damage = 0;
[XmlAttribute("zoom_max")] public float zoom_max = 30f;
}
Then, you need a simple class often caleed a directory for this Weapon class, which will hold the Weapon classes which are in turn read from XML:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Xml;
using System.Xml.Serialization;
[System.Serializable]
[XmlRoot("weapons")]
public class WeaponDirectory {
[XmlElement("weapon")]
public Weapon[] weapons;
}
Now we need a XML file which is organized like this:
weapons
+weapon
name
damage
zoom_max
+ weapon
name
damage
zoom_max
...
Now we can read the XML file:
using System.Xml.Serialization;
using System.IO;
using System.Text;
using System;
using System.Xml;
using System.Collections.Generic;
public class ReadFromXML: MonoBehaviour {
public Dictionary<string,Weapon>() weaponDictionary;
void ReadWeapons() {
weaponDictionary = new Dictionary<string,Weapon>();
string path = "C:/Weapons.xml";
var xmlSerializer = new XmlSerializer(typeof(WeaponDirectory));
var stream = File.Open(path, FileMode.Open);
var deserializedWeapons = xmlSerializer.Deserialize(stream) as WeaponDirectory;
stream.Close();
for(int i = 0; i < deserializedWeapons.weapons.Length; i++) {
Weapon weapon = deserializedWeapons.weapons[i];
Manager.world.weapons.Add (weapon.name, weapon);
}
}
}