I has couple of .NET 1.1 web applications use web.config to store most of the application settings. While releasing new version, I need to ship new settings with default value (with comments), and also retain existing customer settings.

Below is my prototype code to update web.config from another.

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Collections.Specialized;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            ConfigManager loConfig = new ConfigManager();
            ConfigManager loConfig2 = new ConfigManager();

            loConfig.ReadKeysFromConfig(@"c:\Web.config");
            loConfig2.ReadKeysFromConfig(@"c:\web1.config");

            foreach (string lo in loConfig2.AppSettings.Keys)
            {
                string lcvalue = loConfig2.AppSettings[lo];

                if (lcvalue != "")
                {
                    loConfig.AppSettings[lo] = lcvalue;
                }

                Console.WriteLine("Key=" + lo + " value=" + loConfig.AppSettings[lo]);
            }

            loConfig.WriteKeysToConfig(@"c:\Web.config");

            Console.ReadLine();
        }
    }

    public class ConfigManager
    {
        NameValueCollection _ConfigKeys = new NameValueCollection();

        public NameValueCollection AppSettings
        {
            get
            {
                return _ConfigKeys;
            }
        }

        public void ReadKeysFromConfig(string tcConfigFile)
        {
            string lcKey = "";
            string lcValue = "";

            try
            {
                XmlDocument _xdoc = new XmlDocument();
                _xdoc.Load(tcConfigFile);
                XmlNode xmlnode = _xdoc.SelectSingleNode("/configuration/appSettings");

                foreach (XmlNode loNode in xmlnode.ChildNodes)
                {
                    if (loNode.Name != "#comment")
                    {
                        try
                        {
                            lcKey = loNode.Attributes["key"].InnerText;
                            lcValue = loNode.Attributes["value"].InnerText;

                            _ConfigKeys.Add(lcKey, lcValue);
                        }
                        catch (XmlException ex)
                        {
                            throw ex;
                        }
                    }
                }
            }
            catch (XmlException ex)
            {
                throw ex;
            }
        }

        public void WriteKeysToConfig(string tcConfigFile)
        {
            XmlNode xmlnode = null;

            try
            {
                XmlDocument _xdoc = new XmlDocument();
                _xdoc.Load(tcConfigFile);

                foreach (string lckey in _ConfigKeys.Keys)
                {
                    xmlnode = _xdoc.SelectSingleNode(@"/configuration/appSettings/add[@key='" + lckey + "']");

                    if (xmlnode == null)
                    {
                        xmlnode = _xdoc.CreateNode(XmlNodeType.Element, "add", null);
                        XmlAttribute xmlkeyattr = _xdoc.CreateAttribute("key");
                        xmlkeyattr.Value = lckey;
                        XmlAttribute xmlvalueattr = _xdoc.CreateAttribute("value");
                        xmlvalueattr.Value = _ConfigKeys[lckey];

                        xmlnode.Attributes.Append(xmlkeyattr);
                        xmlnode.Attributes.Append(xmlvalueattr);

                        XmlNode xmlparent = _xdoc.SelectSingleNode(@"/configuration/appSettings");

                        if (xmlparent == null)
                        {
                            XmlNode AppSettingNode = _xdoc.CreateNode(XmlNodeType.Element, "appSettings", null);
                            xmlparent.AppendChild(AppSettingNode);
                        }

                        xmlparent.AppendChild(xmlnode);
                    }
                    else
                    {
                        xmlnode.Attributes.GetNamedItem("value").Value = _ConfigKeys[lckey];
                    }
                }

                _xdoc.Save(tcConfigFile);
            }
            catch (XmlException ex)
            {
                throw ex;
            }
        }
    }
}

It is my first touch to XMLDocument. It looks complex, but actually not that difficult :)

Reference:

West-wind Configuration Class