How to iterate through every node in xml?

I’m trying to make a loader which can use the maps made in Tiled, everything works fine when there is only one layer at a time, but after that it only loads the first one, and I have no idea why.

while reader.Read():
    if reader.Name == "layer":
        Debug.Log(reader.GetAttribute("name"))

As far as I know the Read() method should iterate through the whole xml, so what am I doing wrong? Also, the layers have other elements, and I can iterate through them without problem with this code:

if reader.Name == "tile":
    Debug.Log(reader.Name)

…but only in the first “layer” node. I hope you understood my problem, this whole xml thing is really new for me, so I may used wrong words.
So the problem is. I have a file like this

<map>
 <layer name="first">
  <tile gid=1>
 </layer>
 <layer name="second">
  <tile gid=2>
 </layer>
</map>

How can access the elements of the layer named “second”?

That’s not how you normally access nodes in an XML file. There’s a much easier way. I always use it, pretty easy stuph.

Set your xml file like this:

< Map >
  < Layer_00 >
     < Name > first < /Name >
     < GID > 1 < /GID >
  < /Layer_00 >       
  < Layer_01 >
     < Name > second < /Name >
     < GID > 2 < /GID >
  < /Layer_01 >
< /Map >

(Ignore the spaces between the < and >)

I hope you’re using C#, if so I’ll start from scratch:

0- You’ll need the System.Xml namepace, so using System.Xml;

1- First you load your document:

var doc = new XmlDocument(); // create an empty doc
doc.Load(dbPath);            // load the doc, dbPath is a string

2- Now, to read elements values (I’m gonna demo this by looping over your file)

A) Using a for loop:
var baseNode = doc.DocumentElement; // DocumentElement is the base/head node of all your xml document, in this case, it’s Map
int nNodes = baseNode.ChildNodes.Count; // since it’s a ‘node’ this means that I could access its “ChildNodes” - which is a List of “XmlNode” - since it’s a list, I could get its no. elements by the Count property.

for (int i = 0; i < nNodes; i++)
{
  var childNode = baseNode.ChildNodes*;*

Debug.Log(childNode.name); // should print layer_01, layer_02, etc
Debug.Log(childNode.SelectSingleNode(“Name”).InnerText) // in the first loop, it will print “first”, in the 2nd will print “second”, etc
Debug.Log(childNode.SelectSingleNode(“GID”).InnerText) // in the first loop, will print “1”
}
B) Using a foreach loop, which is shorter code-wise:
foreach(var node in baseNode.ChildNodes)
{
Debug.Log(node.name);
Debug.Log(node.SelectSingleNode(“Name”).InnerText);
Debug.Log(node.SelectSingleNode(“GID”).InnerText);
}
SelectSingleNode(string nodeName) is exactly what it sounds like, it selects a node by its name :slight_smile: - The InnerText property returns the value of whatever inside that node VALUE - As a string of course. (If you need to have int values, booleans, etc you just cast them when you’re getting them via ConvertTo.XXX or maybe normal casts will work)
The InnerText property has a setter as well, so you could do:
node.SelectSingleNode(“Name”).InnerText = “Butthead”;
3- Since you’re only reading, you don’t need to save your doc, but if you’re writing you need to doc.Save(dbPath);
I have a summary of all important XML classes and simple usages I wrote a while ago, [here you go][1].
For good XML tuts, you can checkout the [newboston’s C# series][2], look for the XML stuff (that’s where I learned good XML)
Good luck.
[1]: Dropbox - Error - Simplify your life
[2]: The New Boston - Shopping Tips, Products Reviews