XML Configuration File for Your Applications
How to read and create simple XML configuration files for your application
Introduction
Quite often, it is impossible to create an application that works for all users. Each user may have his own preferences or requirements and the application needs to be able to adjust accordingly at runtime to please the user. One of the easier approaches is to use configuration files to remember the user's preferences. This article explain the usage of the XML configuration parser and writer that I created for my projects. You can download the .NET solution file above, which includes the H2Configurator
class library project and a sample application project.
Background
Over the years, I found that standardizing a configuration file format for my applications can save me a lot of time and effort. However, picking a format is not so trivial. There are many choices such as the DOS way, UNIX way, Apache way, and about hundreds other ways. So to make life easier, I just randomly pick one ... the XML way. :-)
No, just kidding. I didn't just randomly pick XML. The reasons for using XML as my configuration file format are:
- XML parsing functions are available in almost all programming languages, and
- It is human readable if I ever need to mess with file directly
So you ask, "Why create a custom class library? Why not just use the .NET's XML classes directly?" Well, you can do that. In fact, it is probably the best way to parse and create really complex XML files. But for all the projects I ever worked on, it would be an overkill and waste of time trying to build and read configuration files this way because I have only one very specific need -- manipulate simple configuration files.
Configuration Formats
Before we look into the programming part, let's first decide what the configuration files should looks like.
Let's say we want to remember the user's email addresses, home and cell phone numbers, and login information in the configuration file. Here is how I would write the configuration file:
<configuration>
<email>jdoe@company.dom</email>
<email>jdoe@personal.dom</email>
<phone type="home">555-555-1111</phone>
<phone type="cell">555-555-2222</phone>
<login id="jdoe" pass="mypass" />
</configuration>
Note that all configuration entries are wrapped inside the <configuration> </configuration>
tag pair. For each entry, there are 3 major elements -- name, attributes, and value. Let's examine the entries:
<email>jdoe@company.dom</email>
<email>jdoe@personal.com</email>
These two entries both have the name "email
" but each with a different value, "jdoe@company.dom
" and "jdoe@personal.dom
". So in this case, the user has two email addresses.
<phone type="home">555-555-1111</phone>
<phone type="cell">555-555-2222</phone>
These two entries both have the same name "phone
" and both contains the attribute name "type
" but with different attribute values of "home
" and "cell
"; each entry also has a different value of "555-555-1111
" and "555-555-2222
", respectively.
<login id="jdoe" pass="mypass" />
This entry has a name "login
" and two attributes "id
" and "mypass
" with the attribute values "jdoe
" and "mypass
", respectively. Note that, unlike the entries above, this entry does not have a value for itself.
Using the Code
Now that we have the configuration file, let's take a look at the class library and see how to use it.
The class library has three classes in the H2Utilities
namespace:
H2Configurator
is the main class that you use to read, write, and create configuration files.H2ConfigEntry
is the class that manipulates individual configuration entries.H2ConfigAttribute
is the class that manipulates individual attributes in each entry.
The actual implementation of these 3 classes are quite straightforward so I won't get into details. If you are interested in the actual implementation, please write a request in the comment section and I'll try to answer your questions.
Creating the Configuration File
Let's get our feet wet by first creating the XML configurations as shown before. Here is the code segment:
using H2Utilities;
// ... other codes ...
public void CreateConfigurationFile()
{
//========================================
// Create two new entries for emails
//========================================
H2ConfigEntry email1 = new H2ConfigEntry();
H2ConfigEntry email2 = new H2ConfigEntry();
// Set the values of the two email entries
email1.Name = "email";
email1.Value = "jdoe@company.dom";
email2.Name = "email";
email2.Value = "jdoe@personal.dom";
//========================================
// Create two new entries for phones
//========================================
H2ConfigEntry phone1 = new H2ConfigEntry();
H2ConfigEntry phone2 = new H2ConfigEntry();
// Set the name, attribute, and value for phone1
phone1.Name = "phone";
phone1.AddAttribute("type", "home"); // attribute name, attribute value
phone1.Value = "555-555-1111";
// Set the name, attribute, and value for phone2
phone2.Name = "phone";
phone2.AddAttribute("type", "cell"); // attribute name, attribute value
phone2.Value = "555-555-2222";
//========================================
// Create a new entry for login
//========================================
H2ConfigEntry login = new H2ConfigEntry();
// Set the name and attributes for the login entry
login.Name = "login";
login.AddAttribute("id", "jdoe"); // attribute name, attribute value
login.AddAttribute("pass", "mypass"); // attribute name, attribute value
//========================================
// Add all entries to our configuration
// and save the configuration to a file.
//========================================
// Create a new configurator object
H2Configurator config = new H2Configurator();
// Add the two email entries to our configuration
config.AddEntry(email1);
config.AddEntry(email2);
// Add the two phone entries to our configuration
config.AddEntry(phone1);
config.AddEntry(phone2);
// Add the login to our configuration
config.AddEntry(login);
// Save the configuration to a file
config.Save("my.config");
}
If you want to have the function return the XML configuration string instead of saving it to a file, you can change the line...
config.Save("my.config");
... to...
return config.ExportXml();
... and change the function declaration to:
public string CreateConfigurationFile()
Reading and Manipulating the Configuration File
Now we have created the configuration file and you know how to add entries and attributes. We will now find out how to read the configuration file and then change/delete entries and attributes. The following is the code segment:
using H2Utilities;
// ... other codes ...
public void ReadAndManipulate()
{
//===========================================
// Read configuration file by supplying
// the file name in the Constructor
//===========================================
H2Configurator config = new H2Configurator("my.config");
//===========================================
// Get and print the user's phone numbers
//===========================================
List<H2ConfigEntry> allPhones = config.GetEntriesByName("phone");
// Print all phones
foreach (H2ConfigEntry phone in allPhones)
{
// Get phone type and phone number
string phoneType = phone.GetAttributeByName("type").Value;
string phoneNum = phone.Value;
// Print phone info to console
Console.WriteLine(phoneType + ": " + phoneNum);
}
//===========================================
// Deleting the cell phone info
//===========================================
// Find the cell phone entry and delete it
foreach (H2ConfigEntry phone in allPhones)
{
// Check if this is the cell phone
if (phone.GetAttributeByName("type").Value.ToUpper() == "CELL")
{
// Remove the cell phone entry
config.RemoveEntry(phone);
break;
}
}
//==========================================
// Change the home phone entry to "fax" and
// modify the phone number.
//==========================================
// Find the home phone entry
foreach (H2ConfigEntry phone in allPhones)
{
// Get the "type" attribute
string phoneType = phone.GetAttributeByName("type");
// Check if this is the home phone
if (phoneType.Value.ToUpper() == "HOME")
{
// Change the type to "fax"
phoneType.Value = "fax";
// Change the phone number
phone.Value = "555-555-3333";
// OK. Done.
break;
}
}
//==========================================
// Save the configuration file
//==========================================
config.Save("my.config");
}
That's it. I hope you find this library useful and able to save a few minutes of your coding time. Enjoy.
History
- 2009 Feb 06: Submitted first version of the article and code