Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Copying & Appending an Element to an XML Document without buffering to RAM

Tags:

c#

xml

As the title suggests I need to append log data to an XML file without buffering to RAM. The XML File is made up of LogEntry elements, which contain 82 child elements that contain data. These files can get quite large and seeing as it will form part of a Windows CE6 program we have very limited memory.

Having done a fair amount of research it's apparent that the most common methods are to use XDocument or Linq to XML to read in the existing document before appending to it and writing out the new document. Using XmlWriter and XmlReader in concert seems to be the best way for me to append to the file, but all my attempts so far are hugely impractical and require IF Statements to direct what to write in order to prevent duplicate or data less elements being written.

The essence of what I'm doing is:

//Create an XmlReader to read current WorkLog.
using (XmlReader xmlRead = XmlTextReader.Create("WorkLog.xml"))
{
   //Create a XmlWriterSettings and set indent 
   //to true to correctly format the document
   XmlWriterSettings writerSettings = new XmlWriterSettings();
   writerSettings.Indent = true;
   writerSettings.IndentChars = "\t";

   //Create a new XmlWriter to output to
   using (XmlWriter xmlWriter = XmlWriter.Create("New.xml", writerSettings))
   {
      //Starts the document
      xmlWriter.WriteStartDocument();

      //While the XmlReader is still reading (essentially !EOF)
      while (xmlRead.Read())
      {
         //FSM to direct writing of OLD Log data to new file
         switch (xmlRead.NodeType)
         {
            case XmlNodeType.Element:
               //Handle the copying of an element node
               //Contains many if statements to handle root node &  
               //attributes and to skip nodes that contain text
               break;
            case XmlNodeType.Text:
               //Handle the copying of an text node
               break;
            case XmlNodeType.EndElement: 
               //Handle the copying of an End Element node
               break;
         }
      }

      xmlWriter.WriteEndDocument();
   }
}

I'm confident I could append to the file this way but it is highly impractical to do so - does anyone know of any memory efficient methods that my hours of searching hasn't turned up?

I'm happy to post my current code to do this if required - but as I mentioned it is extremely large and is actually pretty nasty at the moment so I'll leave it out for now.

like image 317
Kobunite Avatar asked Feb 16 '23 17:02

Kobunite


2 Answers

if you have known your xml structure, consider using stream writer. 1. open file as filestream 2. move point to the tag you wanna replace, like: , move your point(position) to the "<" 3. write your log data in the right xml format and write the "" at the end of write

"process the xml file with text editor"

like image 154
Eugene Avatar answered May 06 '23 11:05

Eugene


If a hack is justified, I would go to the end of the file, rewind past the end tag and write the new element and the end tag. For further improvement, you could even cache the offset of the beginning of last element.

like image 31
Miserable Variable Avatar answered May 06 '23 10:05

Miserable Variable