klce
klce

Reputation: 220

Writing into an XML file and only saving changes at the end

I have an XML file which I need to write to. I can successfully do so already using the following:

//Code to open the File
public void Open(string FileName, string FilePath)
    {
        try
        {
            XmlDoc = new XmlDocument();
            XmlDoc.PreserveWhitespace = true;
            XmlnsManager = new XmlNamespaceManager(mXmlDoc.NameTable);
            XmlnsManager.AddNamespace("", "urn:xmldata-schema");

            FileStream = new FileStream(@Path.Combine(FilePath, FileName),
                FileMode.Open, FileAccess.ReadWrite);

            XmlDoc.Load(FileStream);

        }
        catch (Exception inException)
        {
            MessageBox.Show(inException.ToString());
        }
    }

   //Code to write to the file
   public void SetValueByElementName(string Name, string Value)
   {
        try
        {
            XmlNode node = XmlDoc.SelectSingleNode("//" + inElementID, XmlnsManager);
            node.InnerText = Value;

        }
        catch (Exception inException)
        {
            MessageBox.Show(inException.ToString());
        }
    }

//Code to save the file
public void Save()
    {

        try
        {
            XmlDoc.Save(@Path.Combine(XmlFilePath, XmlFileName));
            IsFileModified = false;
        }
        catch (Exception inException)
        {
            MessageBox.Show(inException.ToString());
        }
    }

However, the implementation of this class, is that every time I need to write something into the XML file, I have to save it. Now, I was told that I have to change this, and what should happen is that I have to save it only once which is at the end when reading/writing is done. How can I achieve this?

EDIT:

I forgot to add this: One thing I don't quite understand is that the implementation requires to close the file stream immediately.

 //Code to close stream
 private void CloseStream()
    {
        try
        {
            FileStream.Close();
        }
        catch (Exception inException)
        {
            MessageBox.Show(inException.ToString());
        }
    }

The flow is as follows:

  1. OpenFile (then immediately close it)
  2. CloseFile
  3. SetFirstElementValueByElementId (change something in the xml file).
  4. SaveFile (has to be called everytime I make changes, otherwise they won't reflect on the file).

Upvotes: 0

Views: 3578

Answers (2)

Nisar Ahmed
Nisar Ahmed

Reputation: 67

You could simply copy contents of the FileStream into MemoryStream and use it until you want to save the file to the disk.

The link below explains how to do it.

Save and load to Memory Stream

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1503280

Just separate the lifecycle into three parts:

  • Load the XML file (I would recommend using LINQ to XML instead of the old XmlDocument API, but whatever you need to do...)
  • Perform all the modifications you need to
  • Save it at the end

You haven't really explained what's happening in the middle step, but there are two potential options:

  • Either you can let the rest of your code know about the XML directly
  • You can hide the XML within another class - so you'd have an XmlDocument or XDocument as a member variable in the class, and the calling code would look something like:

    Foo foo = Foo.Load("test.xml");
    // Whatever you need here...
    foreach (var data in someSource)
    {
        foo.UpdateWithData(data);
    }
    foo.Save("test.xml");
    

    That way the only class that needs to understand the structure of your XML file is Foo. (You'd rename it to something more appropriate, of course.)

Upvotes: 1

Related Questions