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

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 :slight_smile:
Just download the XML parser from the 2
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 :slight_smile:
Apologies for typing mistakes (if any)

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*;*
  •          Manager.world.weapons.Add (weapon.name, weapon);*
    
  •     }*
    

}
}