Often there are a number of properties that your application depends upon. Everything from the name of the data source to information required to wire your beans together in ColdSpring or LightWire. The question is where to put them. One way is just to sprinkle them over your code, setting the properties wherever they are required. In practice that can make your applications hard to maintain as you have to search through all of your files to find the various properties you might want to change.
So, most developers create some sort of centralized file (or set of files) for storing those variables. There are three common approaches: a programmatic cfinclude, an ini file and an XML file.
INI or XML?
For simple config files, as Hal Helms pointed out in the first half of a great article, you can use an INI file (in the second half he suggests that XML is a better approach – as does Joe Rinehart in a separate article - thanks Jim for the links!).
While INI files can work for simple data, as soon as you get data that has depth to it (perhaps a list of objects that each have properties), INI files get pretty messy, pretty fast. And given that most applications (and hence most configuration files) get bigger and more complex over time, it is worth starting out with XML if you want a static configuration file. Jim Collins created a nice project the other day to make it easier to get started with your own XML config files.
The Benefits of XML
Some of the benefits of an XML configuration file are as follows:
- You can use standard third party tools to create the XML config file and to check it for syntactical and semantic accuracy if you publish a DTD.
- There is an argument that you should distinguish between configuration (data) and programming (code). XML enforces that distinction.
- While Jim's example is pretty simple, you can create sophisticated schemas for "deep" information which is particularly useful when you have data that contains data that contains data. Doing that in a traditional config file can be a real problem.
- XML configs are designed to be written programmatically as well as being able to be edited manually in anything from a text editor to an XML editor.
- Anyone technical working with your application will know exactly what an XML file is and how to use and validate it against a DTD.
- You have much more granularity for capturing errors. If you include a struct, any syntax error will bring your application (or your try/catch block) down. With XML you can validate against DTD and then validate given values knowing you will have a syntactically and semantically accurate data structure.
Jared also make some good comments (scroll down to the comments) about why he prefers to use XML files.
And if you can think of any other benefits to XML, please post them in the comments below – this was a quick posting so I’m sure the list isn’t comprehensive.
However, there are things that you can not do easily with an XML file. What happens if you want the base directory path to include #application.name# or to use expand path or other functions to dynamically set other properties? What about if you want to change the datasource between your production and test db based on the value of a URL variable or a session key? What happens if you want to set a time based on Now() or to take advantage of all of the other features that a programming language provides?
Well, a configuration file is for manually entered configuration information. Anything you configure based on variables such as application.name or functions like now() or expandpath() shouldn’t be in your config file – it should be elsewhere in your configuration routine.
As for changing data source based on a URL or session key, you have two XML files with one for each data source. This does make it important that your applications support multiple XML config files. You don’t want to have to put the same directory configuration information into two different config files just because you want to be able to change data source programmatically – that would not be very DRY (Don’t Repeat Yourself). Another approach would be to include awareness of production vs. test values into your XML schema. That can work, but I tend to prefer to keep the schemas simpler and have lots of simple little XML files otherwise your schema could get a little complex if there were lots of potential classes of variability they needed to know about (although any thoughts on adding such information to schemas would be appreciated).
Should you use XML for Configuration?
Firstly, I must state: I don’t like XML. I find it verbose, ugly and with an extremely high signal to noise ration. I personally think XML is visually extremely intrusive and annoying, and the thought of explicitly repeating structural information in every record seems painfully inefficient. That said, I've looked at other formats (such as JSON, for instance) and I understand why there is much more chance for error (especially when a file is manually created) if you don't have all of that redundant information with each record.
There are valid use cases where a programmatic config file makes sense. Martin Fowler had some good comments about programmatic config files. However, most of the time, an XML config file makes more sense and if necessary you can just support programmatic as well as XML interfaces to your configuration information.