-1

i have this xml (it's trimmed for example purposes)

<?xml version="1.0" encoding="utf-8"?>
<levels>
    <level><!-- level 1 ! -->
        <name>Level 1</name>
        <title>Title 01</title>
        <crystal01>false</crystal01>
        <crystal02>false</crystal03>
        <crystal02label>Label 1</crystal03label>
        <crystal03>false</crystal04>
    </level>
    <level><!-- level 2 ! -->
        <name>Level 2</name>
        <title>Title 02</title>
        <crystal01>true</crystal01>
        <crystal02>true</crystal03>
        <crystal02label>Label 2</crystal03label>
        <crystal03>false</crystal04>
    </level>
</levels>

And i use this Script to load the data to some variables

public class LoadXmlData : MonoBehaviour // the Class
{
    public int actualLevel = 1;
    static int LevelMaxNumber;
    static int WaipointCounter = 0;

    public static string lvlname = "";
    public static string lvltitle = "";

    public static string crystal01 = "";
    public static string crystal02 = "";
    public static string crystal02label = "";
    public static string crystal03 = "";

    public TextAsset XMLData;

    List<Dictionary<string,string>> levels = new List<Dictionary<string,string>>();
    Dictionary<string,string> obj;


    void Start()
    {    GetLevel();
        StartCoroutine(LevelLoadInfo(0.0F));
        LevelMaxNumber = levels.Count;
    }

    public void GetLevel()
    {
        XmlDocument xmlDoc = new XmlDocument(); // xmlDoc is the new xml document.
        xmlDoc.LoadXml(XMLData.text); // load the file.
        XmlNodeList levelsList = xmlDoc.GetElementsByTagName("level"); // array of the level nodes.

        foreach (XmlNode levelInfo in levelsList)
        {
            XmlNodeList levelcontent = levelInfo.ChildNodes;
            obj = new Dictionary<string,string>();

            foreach (XmlNode levelsItens in levelcontent) // levels itens nodes.
            {
                if(levelsItens.Name == "name")
                {
                    obj.Add("name",levelsItens.InnerText); // put this in the dictionary.
                }


                if(levelsItens.Name == "title")
                {
                    obj.Add("title",levelsItens.InnerText); // put this in the dictionary.
                }


                if(levelsItens.Name == "crystal01")
                {
                    obj.Add("crystal01",levelsItens.InnerText); // put this in the dictionary.

                }

                if(levelsItens.Name == "crystal02")
                {
                    obj.Add("crystal02",levelsItens.InnerText); // put this in the dictionary.

                }

                if(levelsItens.Name == "crystal02label")
                {
                    obj.Add("crystal02label",levelsItens.InnerText); // put this in the dictionary.

                }


                if(levelsItens.Name == "crystal03")
                {
                    obj.Add("crystal03",levelsItens.InnerText); // put this in the dictionary.

                }

            }
            levels.Add(obj); // add whole obj dictionary in the levels[].
        }
    }


    IEnumerator LevelLoadInfo(float Wait)
    {
        levels[actualLevel-1].TryGetValue("name",out lvlname);

        levels[actualLevel-1].TryGetValue("title",out lvltitle);

        levels[actualLevel-1].TryGetValue("crystal01",out crystal01);

        levels[actualLevel-1].TryGetValue("crystal02",out crystal02);

        levels[actualLevel-1].TryGetValue("crystal02label",out crystal02label);

        levels[actualLevel-1].TryGetValue("crystal03",out crystal03);

        yield return new WaitForSeconds(Wait);

    }

    void Update()
    {
    }

}

Everything is working fine, but im really struggling for a few days to make a function to access some node, ovewrite it's data and save the xml, i know that it's somewhat a simple thing but i dont get it (im a 3d artist, im programming since last year, so, still in learning phase), For example, How could i edit the "crystal02" value in level 2 and save the xml? Thanks in advance!

Mauricio
  • 3
  • 1

1 Answers1

0

You have to fix up your XML a little bit so it will parse. Opening node names need to match closing node names, so from this:

<crystal02>false</crystal03>

to this:

<crystal02>false</crystal02>

To answer your question about updating a single element, since you're using XmlDocument to read your string, here is how you might go about finding a single element by XPath, updating its value in the XmlDocument, and then serializing the XmlDocument back to a string. Your Update method might look something like this:

var doc = new System.Xml.XmlDocument();
// strXml is the string containing your XML from XMLData.Text
doc.LoadXml(strXml);
// Find the node by an XPath expression
var l2cr3 = (XmlElement) doc.SelectSingleNode("levels/level[name='Level 2']/crystal03");
// Update it
l2cr3.InnerText = "true";
// Update the string in memory
var sbOut = new System.Text.StringBuilder ();
using (var writer = XmlWriter.Create(sbOut)) {
    doc.Save (writer);
}
strXml = sbOut.ToString ();

This will update the string of XML in memory. It's not going to persist to a file. If you want to persist to a file, you might want to use doc.Load("path/to/file.xml") and doc.Save("path/to/file.xml");

I noticed your string is actually coming from a TextAsset (assuming Unity), and if that's the case, I'm not sure how you want to persist the updated XML string back to a file or even if you want to do that. If you do, that's a different question, but the Unity manual says this:

It is not intended for text file generation at runtime. For that you will need to use traditional Input/Output programming techniques to read and write external files.

DaveC
  • 364
  • 3
  • 10
  • Thanks! that xml typo was made when copy pasting the xml here, "SelectSingleNode" was what i was searching for, currently im testing, but it's already working, thanks again DaveC – Mauricio Oct 13 '14 at 17:27