Search code examples
c#xmldocumentunity-game-enginedelayed-execution

Unity XmlDocument function not always working


Is there anything to consider when using XmlDocument function in unity3d? I'm having this weird problem: When the function which uses XmlDocument is called from Awake() or OnGUI() the document is edited successfully. But when it's called from inside a button event, event tough I get a well edited string before saving the document, it's not able to modify the document itself.

Function that edits the file (sometimes):

    public static void addTestProfile () {

            string path = Application.dataPath + "/Documents/Profiles.xml";
            Hashtable tempTable = new Hashtable();
            tempTable.Add("user", "chuck II");
            tempTable.Add("url", "funny");
            tempTable.Add("passwrod", "1234asdf");
            General.StoreProfile(tempTable, path);
        }


public static void StoreProfile(Hashtable profile, string path) {
        Debug.Log("profile to store name: " + profile["password"]);
        XmlDocument doc = new XmlDocument();
        doc.Load(profilesPath);

        XmlElement element = doc.CreateElement("Profile");

        XmlElement innerElement1 = doc.CreateElement("user");
        innerElement1.InnerText = profile["user"] as string;
        element.AppendChild(innerElement1);

        XmlElement innerElement2 = doc.CreateElement("url");
        innerElement2.InnerText = profile["url"] as string;
        element.AppendChild(innerElement2);

        XmlElement innerElement3 = doc.CreateElement("password");
        innerElement3.InnerText = profile["password"] as string;
        element.AppendChild(innerElement3);
        doc.DocumentElement.AppendChild(element);

        doc.Save(profilesPath);
        Debug.Log(doc.InnerXml);
    }

I created a new project just to test this problem, the file is not edited when called just before calling Application.loadLevel();

Here it works well and the file itself is edited:

void OnGUI () {
         General.addTestProfile();  // General is the singleton class that contains the function implementation
}

But some how this is not working:

// GUI Save btn
if (GUI.Button(new Rect(255, 20, 60, 35), "Add")) {
      General.addTestProfile();   // General is the singleton class that contains the function implementation
      Application.LoadLevel(0);
}

When I print the resultant string right before the save() xmlDocument function, it shows the new item but somehow the xml file remains the same. Am I missing something important maybe related to the execution order? Something like timeout?


Solution

  • When it jumped back to scene 1, it was re-writing the original file.

    "Debug.Log" sucks! , this instruction never printed the second call to createProfilesFile() function. So just one line was missing:

    if (System.IO.File.Exists(profilesPath)) return;
    

    Here the createProfilesFile() function:

    public static void CreateProfilesFile (string path) {
        Debug.Log("create init");      // This line wasn't called the second time ... 
    
        if (System.IO.File.Exists(path)) return;
    
        // Create a new file specified path
        XmlTextWriter textWriter = new XmlTextWriter(path,null);
        // Opens the document
        textWriter.WriteStartDocument();
        // Write comments
        textWriter.WriteComment("This document contains the profiles that have been created.");
        textWriter.WriteStartElement("Profiles");
            textWriter.WriteStartElement("Profile");
                textWriter.WriteStartElement("user");
                    textWriter.WriteString("foo user");
                textWriter.WriteEndElement();
                textWriter.WriteStartElement("url");
                    textWriter.WriteString("foo url");
                textWriter.WriteEndElement();       
                textWriter.WriteStartElement("password");
                    textWriter.WriteString("foo password");
                textWriter.WriteEndElement();
            textWriter.WriteEndElement();
        textWriter.WriteEndElement();
        // Ends the document.
        textWriter.WriteEndDocument();
        // close writer
        textWriter.Close();
    }