Arvo Bowen
Arvo Bowen

Reputation: 4929

What's the best way to update xml in a file?

I have been looking all over for the best way to update xml in a file. I have just switched over to using XmlReader (coming from the XDocument method) for speed (not having to read the entire file in memory).

My XmlReader method works perfect and when I need to read a value, it opens the xml, starts reading and ONLY reads up to the node needed, then closes everything. It's very fast and effective.

Now that I have that working I want to make a method that UPDATES xml that is already in place. I would like to keep to the same idea and ONLY read in memory what is needed. So the idea would be, read up until the node I'm changing then use the writer to UPDATE that value.

Everything I have seen has a XmlReader reading while using an XmlWriter writing everything. If I did that I would assume that I would have to let it run through the entire file just like the XDocument would do. As an example this answer.

Is it possible to maybe just use the reader and read up to the node I'm trying to edit then change the innerxml or something?

What's the fastest and most efficient method to update XML in a file?

Upvotes: 2

Views: 8031

Answers (1)

Scott Dorman
Scott Dorman

Reputation: 42516

By design, XmlReader represents a "read-only forward-only" view of the document and cannot be used to update the content. Using the Load method of either XmlDocument, XDocument or XElement, will still cause the entire file to be read in to memory. (Under the hood, XDocument and XElement still use an XmlReader.) However, you can combine using a raw XmlReader and XElement together using the overloads of the Load method which take an XmlReader.

You don't describe your XML structure, but you would want to do something similar to this:

var reader = XmlReader.Create(@"file://c:\test.xml");  
var document = XElement.Load(reader);
document.Add(new XElement("branch", "leaves"));
document.Save("Tree.xml");

To find a specific node (for example, with a specific attribute value), you'd want to do something similar to this:

var node = document.Descendants("branch")
                   .SingleOrDefault(e => (string)e.Attribute("name") == "foo");

Upvotes: 2

Related Questions