tags:

views:

1767

answers:

6

I'm trying to look at the best way of changing the value of an element in XML.

<MyXmlType>
   <MyXmlElement>Value</MyXmlElement>
</MyXmlType>

What is the easiest and/or best way to change "Value" in C#?

I've looked at XMLDocument and it will cause a load of the whole XML document to memory. Could you do it safely with the XMLReader. The problem is changing the value and emitting it back seems like an interesting conundrum.

Cheers :D

+1  A: 

You could use an XmlReader to read into a class that pumps the data back out through an XmlWriter and scan for the element between the read/write, changing the value as necessary.

Honestly, I'm a little surprised that your XML file is so huge you are worried about memory consumption... not saying it's never an issue. Without more info, I can't say your hypothetical XML file isn't 50gb, but in many cases loading files that seem large into memory long enough to manipulate isn't quite as big a deal as you might think.

Rex M
Base64 encoded binary images :'(
Spence
A: 

EDIT: didn't see your clause about XmlDocument. XmlReader does just that. You can't edit xml files with this class.

You want XmlWriter. However, in case it's still helpful, here's the code for XmlDocument.

private void changeXMLVal(string element, string value)
{
    try
    {
        string fileLoc = "PATH_TO_XML_FILE";
        XmlDocument doc = new XmlDocument();
        doc.Load(fileLoc);
        XmlNode node = doc.SelectSingleNode("/MyXmlType/" + element);
        if (node != null)
        {
            node.InnerText = value;
        }
        else
        {
            XmlNode root = doc.DocumentElement;
            XmlElement elem;
            elem = doc.CreateElement(element);
            elem.InnerText = value;
            root.AppendChild(elem);
        }
        doc.Save(fileLoc);
        doc = null;
    }
    catch (Exception)
    {
        /*
         * Possible Exceptions:
         *  System.ArgumentException
         *  System.ArgumentNullException
         *  System.InvalidOperationException
         *  System.IO.DirectoryNotFoundException
         *  System.IO.FileNotFoundException
         *  System.IO.IOException
         *  System.IO.PathTooLongException
         *  System.NotSupportedException
         *  System.Security.SecurityException
         *  System.UnauthorizedAccessException
         *  System.UriFormatException
         *  System.Xml.XmlException
         *  System.Xml.XPath.XPathException
        */
    }
}
Andrew
He specifically asked how to do it *without* using XmlDocument
Rex M
This does correspond to the title of the question, and helped me out. +1
SP
+4  A: 

You could use the System.Xml.Linq namespace stuff for the easiest to read code. This will load the full file into memory.

        XDocument xdoc = XDocument.Parse("file.xml")
        var element = xdoc.Elements("MyXmlElement").Single();
        element.Value = "foo";
        xdoc.Save("file.xml");
Ben Robbins
XML Namespaces gave me grief, but it got me to where I needed to be.Thanks, plus linqy stuff is nice :).Based on the xml I provided your example already works.
Spence
+2  A: 

Have you thought about using Linq to XML? (if you are using .Net 3.0+)

public static XElement ChangeValue(string xmlSnippet, 
    string nodeName,
    string newValue)
{
    XElement snippet = XElement.Parse(xmlSnippet);
    if (snippet != null)
    {
        snippet.Element(nodeName).Value = newValue;
    }
    return snippet;
}

I am guessing XElement will perform better than XmlDocument (althought not sure), the base object for XElement is XObject, and yes, it will have to load the whole document.

Vin
+1  A: 

Using a forward-only reader is definitely going to be the most efficient approach, in which case a XmlReader derivation seems appropriate, to be sure, though it's still more work than using DOM approach that loads the entire file at once.

XmlReader is supposedly an improvement over the SAX XML parser API that originated in the Java world, but which has become a de facto standard in the industry (outside of Microsoft).

If you just want to get the job done quickly, the XmlTextReader exists for that purpose (in .NET).

If you want to learn a de facto standard that is stable (and also available in many programming languages) and which will force you to code very efficiently and elegantly, but which is also extremely flexible, then look into SAX. However, do not bother with SAX itself unless you're going to be creating highly esoteric XML parsers. There are plenty of parsers out there that use SAX under the covers.

Please check out my response about SAX here for a list of SAX resources and a really creative .NET XML parser idea that uses XmlTextReader as its foundation: http://stackoverflow.com/questions/127869/sax-vs-xmltextreader-sax-in-c/546355#546355

EnocNRoll
A: 

Hi I need a small help here. I was trying to change the innertext value of here. After i change the value and save it with Xmldocument object. When I opened the file, I found that it has got saved in this format. Value > Please note this > ">>". I dont know what is happening. Please help... Fayaz