Help Creating XmlNode / XmlAttribute Elegantly

Tech-Archive recommends: Speed Up your PC by fixing your registry

From: David Elliott (Webbert_at_newsgroups.nospam)
Date: 09/02/04


Date: Thu, 02 Sep 2004 08:52:31 -0400

I am creating a configuration class to read / write a standard configuration file.

                <?xml version="1.0" encoding="utf-8"?>
                <configuration>
                        <appSettings>
                                <add key="ConnectionString" value="server=(local);" />
                        </appSettings>
                </configuration>

I am using a XmlDocument for my base implementation.

I am looking to see if there is a better way to add a new node / attribute than using
XmlDocument.InnerXml. I would consider this to be a hack but couldn't really see another
way of doing this without defining namespaces and the like.

I have included the full file below and the lines that I am wondering about are lines: 79, 227, and 266

Thanks,
Dave

===================================

using System;
using System.Xml;
using System.Text;

namespace Storage.Utility.Configuration
{
        /// <summary>
        /// Class for Reading / Writing Configuration Options
        /// </summary>
        public class Configuration
        {
                #region Data Members

                private XmlDocument xmlDoc = null;
                private XmlElement root = null;
                private XmlNode node = null;

                private string filename = null;
                private string queryString = null;

                #endregion
                
                #region Constructor

                public Configuration(string configFileName)
                {
                        filename = configFileName;
                }

                #endregion

                #region Methods

                #region Miscellaneous

                /// <summary>
                /// Initialize the Configuration Class
                /// </summary>
                private void Initialize()
                {
                        LoadConfiguration();
                }

                #endregion

                #region File Access

                /// <summary>
                /// Reload the Configuration File
                /// </summary>
                public void ReloadConfiguration()
                {
                        LoadConfiguration();
                }

                /// <summary>
                /// Save the Configuration File
                /// </summary>
                public void Save()
                {
                        SaveConfiguration();
                }

                /// <summary>
                /// Load the Configuration File
                /// </summary>
                private void LoadConfiguration()
                {
                        try
                        {
                                xmlDoc = new XmlDocument();
                                xmlDoc.Load(filename);
                        }
                        catch (Exception)
                        {
                                // Create Configuration File
                                xmlDoc.InnerXml = "<?xml version=\"1.0\" encoding=\"utf-8\"?><configuration></configuration>";
                        }
                        finally
                        {
                                root = xmlDoc.DocumentElement;
                        }
                }

                /// <summary>
                /// Save the Configuration File
                /// </summary>
                private void SaveConfiguration()
                {
                        try
                        {
                                xmlDoc.Save(filename);
                        }
                        catch (Exception ex)
                        {
                                // Can't do anything
                                throw (ex);
                        }
                }

                #endregion

                #region Retrieve Values

                /// <summary>
                /// Get the Value of the Key
                /// </summary>
                /// <param name="section"></param>
                /// <param name="key"></param>
                /// <returns></returns>
                public string GetValue(string section, string key)
                {
                        try
                        {
                                // Find the Node
                                node = GetValueNode(section, key);
                                if (node != null)
                                {
                                        // Retrieve Value
                                        XmlNode valueNode = node.Attributes.GetNamedItem("value");
                                        return (valueNode.Value);
                                }
                        }
                        catch (Exception)
                        {
                                // Nothing to do
                        }

                        // Error Occurred
                        return (null);
                }

                
                /// <summary>
                /// Find the Node that the Key belongs to
                /// </summary>
                /// <param name="section"></param>
                /// <param name="key"></param>
                /// <returns></returns>
                private XmlNode GetValueNode(string section, string key)
                {
                        try
                        {
                                // XML Search Path
                                queryString = "/configuration/" + section + "/add[@key=\"" + key + "\"]";

                                // Look from the Root of the Document
                                return (root.SelectSingleNode(queryString));
                        }
                        catch (Exception)
                        {
                                // Nothing to do
                        }

                        // Error Occurred
                        return (null);
                }

                #endregion

                #region Store Values

                /// <summary>
                /// Store Key / Value in Configuration File
                /// </summary>
                /// <param name="section"></param>
                /// <param name="key"></param>
                /// <param name="keyValue"></param>
                /// <returns></returns>
                public bool StoreValue(string section, string key, string keyValue)
                {
                        try
                        {
                                // Find Node if it exists
                                node = GetValueNode(section, key);
                                if (node != null)
                                {
                                        // Update Value
                                        node = node.Attributes.GetNamedItem("value");
                                        node.Value = keyValue;
                                        return (true);
                                }
                        
                                // Node Doesn't Exist -> Get/Create Section -> Add Key / Value
                                if (GetSection(section) == true)
                                        return (CreateValueNode(section, key, keyValue));
                        }
                        catch (Exception)
                        {
                                // Nothing to do
                        }

                        // Error Occurred
                        return (false);
                }

                #endregion

                #region Create Nodes

                /// <summary>
                /// Create New Key / Value Entry
                /// </summary>
                /// <param name="section"></param>
                /// <param name="key"></param>
                /// <param name="keyValue"></param>
                /// <returns></returns>
                private bool CreateValueNode(string section, string key, string keyValue)
                {
                        try
                        {
                                // Get Section
                                queryString = "/configuration/" + section;
                                node = root.SelectSingleNode(queryString);

                                // Node Must Exist
                                if (node != null)
                                {
                                        // Create and Add New Key / Value Entry
                                        StringBuilder sb = new StringBuilder(500);
                                        sb.Append("<add key=\""); sb.Append(key); sb.Append("\" ");
                                        sb.Append("value=\""); sb.Append(keyValue); sb.Append("\" />");

                                        node.InnerXml += sb.ToString();
                                        return (true);
                                }
                        }
                        catch (Exception)
                        {
                                // Nothing to do
                        }

                        // Error Occurred
                        return (false);
                }

                /// <summary>
                /// Get / Create a New Configuration Section
                /// </summary>
                /// <param name="section"></param>
                /// <returns></returns>
                private bool GetSection(string section)
                {
                        try
                        {
                                // Does the Section Exist
                                queryString = "/configuration/" + section;
                                node = root.SelectSingleNode(queryString);
                                if (node != null)
                                        return (true);

                                // Get the Configuration Node
                                queryString = "/configuration";
                                node = root.SelectSingleNode(queryString);
                                if (node != null)
                                {
                                        // Create a New Section
                                        StringBuilder sb = new StringBuilder(1000);
                                        sb.Append("<"); sb.Append(section); sb.Append(">");
                                        sb.Append("</"); sb.Append(section); sb.Append(">");

                                        node.InnerXml += sb.ToString();
                                        return (true);
                                }
                        }
                        catch (Exception)
                        {
                                // Nothing to do
                        }

                        // Error Occurred
                        return (false);
                }
                #endregion

                #endregion

        } // Class
}