[XML] Reading ALL attributes from a file

TL;DR version: How to read attributes in an XML file that are children of an element which itself is a child?

I have a XML file that contains data of various items.

The XML file looks like this:

<items>
  <item name="Item 1" value="10" weight="3.0">
    <mods healthMod="0" staminaMod="0" manaMod="0"></mods>
  </item>
  <item name="Item 2" value="20" weight="5.0">
    <mods healthMod="10" staminaMod="0" manaMod="0"></mods>
  </item>
</items>

So,as you can see, the item “base node” has attributes like value and weight. There is also a child element that contains attributes like healthMod, staminaMod and manaMod.

I have created a class that will hold the deserialized data:

[System.Serializable]
[XmlRoot("items")]
public class ItemDirectory {
	[XmlElement("item")]
	public Item[] items;


}

I can successfully read all elements and attributes from the item base nodes with this code:

Dictionary<string,Item> itemDictionary;

public static void FillItemDictionary() {

		itemDictionary = new Dictionary<string,Item>();

		item = new Item();

		string path = "C:/items.xml";


		var xmlSerializer = new XmlSerializer(typeof(ItemDirectory));
		var stream = File.Open(path, FileMode.Open);
		var deserializedItems = xmlSerializer.Deserialize(stream) as ItemDirectory;


		stream.Close();

		for(int i = 0; i < deserializedItems.items.Length; i++) {
			Item itemCur = deserializedItems.items*;*
  •  	itemDictionary.Add (itemCur.name, itemCur);*
    
  •  	//Debug.Log("Item " + i + " name: " + itemCur.name + " Value: " + itemCur.value);*
    
  •  	//Debug.Log(itemDictionary["Item 1"].value);*
    
  •  }*
    
  • }*
    Thereby, it read the items in the XML file and assigns them to a dictionary of items using the Item class:
    [System.Serializable]
    public class Item {

  • [XmlAttribute(“name”)]*

  • public string name = “”;*

  • [XmlAttribute(“type”)] *

  • public string type;*

  • [XmlAttribute(“value”)]*

  • public int value = 0;*

  • [XmlAttribute(“weight”)]*

  • public float weight = 0.0f;*

  • //mods*

  • [XmlAttribute(“healthMod”)]*

  • public int healthMod = 0;*

  • [XmlAttribute(“staminaMod”)]*

  • public int staminaMod = 0;*

  • [XmlAttribute(“manaMod”)]*

  • public int manaMod = 0;*

}

However, this does NOT appear to read and/or assign the nested attributes inside the “mods” element: healthMod, staminaMod, manaMod. How do I do this?

Those attributes are not nested attributes. They are somply attributes of a child object. Since you did not read any child elements at all you have no access to them. You should create another class for your “mods” element and add a List of “mods items” to your Item class

The list should have the attribute [XmlElement(“mods”)] and your mods attributes need to be declared in your mods class.

edit

The Mods class should look like this:

[Serializable]
public class Mods
{
    [XmlAttribute("healthMod")]
    public int healthMod = 0;
    [XmlAttribute("staminaMod")]
    public int staminaMod = 0;
    [XmlAttribute("manaMod")]
    public int manaMod = 0;
}

And your Item class should look like this:

[Serializable]
public class Item
{
    [XmlElement("mods")]
    public List<Mods> mods;

    // your Item attributes here
}

ps: If it’s ensured that it will be exactly one mods element as child you can replace the List< Mods > with a simple Mods variable. However, since XML allows multiple elements as childs you usually have lists or arrays for the child elements.