In my project I have got a listview filled with contacts which are stored in a XML file.

This is the connection between the two of these and basically this is how the contacts are loaded:

Please note that first function is called on form loading:

void LoadContacts()
    {
        string path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
        string phonebook_path = path + "\\Phonebook\\Contacts.xml";
        if (!File.Exists(phonebook_path))
        {
            XmlTextWriter xW = new XmlTextWriter(phonebook_path, Encoding.UTF8);
            xW.WriteStartElement("People");
            xW.WriteEndElement();
            xW.Close();
        }
        XmlDocument xDoc = new XmlDocument();
        xDoc.Load(phonebook_path);
        foreach (XmlNode xNode in xDoc.SelectNodes("People/Person"))
        {
            Person p = new Person();
            p.Name = xNode.SelectSingleNode("Name").InnerText;
            p.Hometown = xNode.SelectSingleNode("Hometown").InnerText;
            p.Address = xNode.SelectSingleNode("Address").InnerText;
            p.Birthday = DateTime.FromFileTime(Convert.ToInt64(xNode.SelectSingleNode("Birthday").InnerText));
            p.Phone = xNode.SelectSingleNode("Phone").InnerText;
            p.Email = xNode.SelectSingleNode("Email").InnerText;
            p.AdditionalInfo = xNode.SelectSingleNode("AdditionalInfo").InnerText;
            people.Add(p);
            listView1.Items.Add(p.Name);
            UserCount();
        }
    }

and then the other one on form closing:

private void Main_FormClosing(object sender, FormClosingEventArgs e)
    {
        XmlDocument xDoc = new XmlDocument();
        string path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
        string phonebook_path = path + "\\Phonebook\\Contacts.xml";
        xDoc.Load(phonebook_path);
        XmlNode xNode = xDoc.SelectSingleNode("People");
        xNode.RemoveAll();
        foreach (Person p in people)
        {
            XmlNode xTop = xDoc.CreateElement("Person");
            XmlNode xName = xDoc.CreateElement("Name");
            XmlNode xHometown = xDoc.CreateElement("Hometown");
            XmlNode xAddress = xDoc.CreateElement("Address");
            XmlNode xBirthday = xDoc.CreateElement("Birthday");
            XmlNode xPhone = xDoc.CreateElement("Phone");
            XmlNode xEmail = xDoc.CreateElement("Email");
            XmlNode xAdditionalInfo = xDoc.CreateElement("AdditionalInfo");
            xName.InnerText = p.Name;
            xHometown.InnerText = p.Hometown;
            xAddress.InnerText = p.Address;
            xBirthday.InnerText = p.Birthday.ToFileTime().ToString();
            xPhone.InnerText = p.Phone;
            xEmail.InnerText = p.Email;
            xAdditionalInfo.InnerText = p.AdditionalInfo;
            xTop.AppendChild(xName);
            xTop.AppendChild(xHometown);
            xTop.AppendChild(xAddress);
            xTop.AppendChild(xBirthday);
            xTop.AppendChild(xPhone);
            xTop.AppendChild(xEmail);
            xTop.AppendChild(xAdditionalInfo);
            xDoc.DocumentElement.AppendChild(xTop);
        }

        xDoc.Save(phonebook_path);
        Sync();
        SetStartup();
    }

I have got an option to import the XML file via method Import() which is called when a button is clicked.

void Import()
    {
        Main f1 = new Main();
        OpenFileDialog BrowseFile = new OpenFileDialog();
        if (BrowseFile.ShowDialog() == System.Windows.Forms.DialogResult.OK)
        {
            Properties.Settings.Default.ImportPath = BrowseFile.FileName;
        }
        string fileName = "Contacts.xml";
        string path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
        string sourcePath = Properties.Settings.Default.ImportPath;
        string targetPath = path + "\\Phonebook\\";
        string destFile = System.IO.Path.Combine(targetPath, fileName);
        System.IO.File.Copy(sourcePath, destFile, true); 
        MessageBox.Show("Contacts have successfully been imported. Please restart your application in order changes to take effect!", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
    }

...Importing is performed perfectly which means I can see the copied XML file in the right place, but when I close the application, all of a sudden XML file turns into previous state somehow which means changes didn't take effect - when I load the app again, there will be no imported contacts.

How can I solve this issue?

Recommended Answers

All 4 Replies

In your FormClosing event, make sure that xDoc actually contains everything you want before calling Save.

And how I am supposed to do so?

No hard feelings please, since I am quite new to c#.

Open it in a your debugger, and look at the xDoc object.

If I were in your position and re-writing the entire file everytime, I wouldn't bother trying to modify the existing one.

Just create a new one from scratch an over-write the existing file.

If you want to continue to modify the existing file, pick whether to use SelectSingleNode or DocumentElement and stick to using that throughout your method. You perform RemoveAll from the xNode which is the People node (I'm assuming this is your root node based on the rest of your code) but then you add the people back in on DocumentElement. In my opinion, you should add them back in on the xNode variable.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.