1

Background

This is my small XML file I made online.

<?xml version="1.0"?>
<movement>
    <skill id = "2">
        <cooldown>5</cooldown>
    </skill>
    <skill id = "3">
        <cooldown>10</cooldown>
    </skill>
</movement>

This is some code I have so far to try to parse it.

    string dataPath  = Application.dataPath + "/Resources/XML/Skills/";
    DirectoryInfo xmlFolder = new DirectoryInfo (dataPath);
    FileInfo[] files = xmlFolder.GetFiles ("*.xml");

    // Loops through each XML file
    foreach (FileInfo file in files) {
        XmlDocument xdoc = new XmlDocument ();
        xdoc.Load (file.ToString ());
        XmlNodeList nodes = xdoc.DocumentElement.SelectNodes ("/movement");
        foreach (XmlNode node in nodes) { // Movement Layer
            foreach (XmlNode skillNode in node.ChildNodes) {
                print (skillNode.Value);
            }
        }
    }

Problem

I am able to access the 5 and 10 values for cooldown, but cannot get the "id" value of the skill. The reason I'm trying to do this is to read the skill IDs into my game and store the information. I pretty much exhausted almost all the methods denoting from XmlNode, such as value and name, but it only returns "skill", and not the value of skill, such as 2 or 3. I feel like I'm missing something really simple here, but I'm having difficulty finding the correct terminology or phrasing for this issue.

Jon
  • 89
  • 1
  • 8
  • Not a solution but please note that your whole file read code is useless. It will work in the Editor but won't work in a build which is pointless. [This](https://stackoverflow.com/questions/41326248/using-resources-folder-in-unity/41326276#41326276) is how to read from the Resources folder. – Programmer Oct 17 '17 at 22:02
  • 1
    @Programmer thank you omg this saved lots of time. – Jon Oct 18 '17 at 01:01

3 Answers3

3

LINQ To XML would make this parsing simpler...

    static void Main(string[] args)
    {
        var doc = 
@"<?xml version=""1.0""?>
<movement>
<skill id = ""2"" >
     <cooldown> 5 </cooldown>
 </skill>
 <skill id = ""3"" >
      <cooldown> 10 </cooldown>
  </skill>
</movement> ";

        var root = XDocument.Parse(doc);
        foreach (var skill in root.Descendants("skill"))
        {
            Console.WriteLine("Skill: {0} \t CoolDOwn: {1}",
                    (int)skill.Attribute("id"),
                    skill.Element("cooldown").Value);
        }

        Console.ReadLine();
    }
bigtlb
  • 1,512
  • 10
  • 16
  • 1
    You could make it prettier using LINQ query syntax, but this gets the job done, and shows you the methods. Notice the LINQ TO XML XElement and XAttribute have explicit conversion operators defined to make it easier to change the string to whatever type it needs to be. https://learn.microsoft.com/en-us/dotnet/api/system.xml.linq.xelement.op_explicit?view=netframework-4.7.1 – bigtlb Oct 17 '17 at 22:06
2

Using xml linq :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);

            var results = doc.Descendants("skill").Select(x => new {
                id = (int)x.Attribute("id"),
                coolDown = (int)x.Element("cooldown")
            }).ToList();
        }
    }
}
jdweng
  • 33,250
  • 2
  • 15
  • 20
0

I would not use XMLDocument for querying purposes IMHO. I find XDocument to be an easier extension off of System.Xml.Linq;

EG:

using System;
using System.Linq;
using System.Xml.Linq;

namespace ConsoleTester
{
    class Program
    {
        static void Main(string[] args)
        {
            //Here I am mocking your file statically, you could iterate here through a file system.
            var xml =
                "<?xml version=\"1.0\"?><movement><skill id = \"2\"><cooldown>5</cooldown></skill><skill id = \"3\"><cooldown>10</cooldown></skill></movement>";

            //Just parse the file from the text obtained from a StreamReader or similar.
            var xdoc = XDocument.Parse(xml);

            //Chain the events of finding the node(s) you want with 'Elements' then continuing on to more, then you want an Attribute and not a node.  Then select it's value.
            xdoc.Elements("movement").Elements("skill").Attributes("id")
                .Select(x => x.Value)
                .ToList()
                .ForEach(x => Console.WriteLine(x));


            Console.ReadLine();
        }
    }
}
djangojazz
  • 14,131
  • 10
  • 56
  • 94