Using XML to Store States and ProvincesBy Rachael Schoenbaum
With every single project I've ever worked on, I've had to deal with displaying U.S. States. Sometimes I needed to include territories like Puerto Rico and the U.S. Virgin Islands; sometimes I needed to include Canadian provinces. It varied across projects so I wanted an easy way to store the information I needed and to be able to easily and quickly add, edit, and delete the information as necessary.
In addition, I wanted a simple way to store the full name and the abbreviation so that it would be easy to switch back and forth within a single application or if the client changed their mind about how they wanted the information to appear. The last thing I wanted to do was to hardcode in the states and provinces into my application.
My solution was to store the state and province information in an XML file, and to create a
module from which I could easily extract the state information. In this article we'll examine this XML file and class,
and see how a DropDownList with the names of states and provinces can be created in just a couple lines of code
Storing State Information as XML
I decided to store the state and province information as an XML file instead of using a traditional relational database. There were a couple of reasons for this decision:
- With the data in XML it's much faster for me to change the list than if it were in a database.
- With the data in XML, implementing the code in new applications is a breeze - I just copy the XML file to the new Web application instead of having to create new tables and reinsert the data.
- It freed me up to do other things - people who aren't database-savvy, but who want control over the data, can modify the list of states without my help. Had I used a relational database for the state information, anytime a change or addition was needed, I'd be the one who'd have to take the time to make the change.
Below is an example XML document. The structure I chose has
<states> as the document root element.
Each state or province is indicated with a
<state> element, with the full name specified in the
name attribute and the abbreviation in the
abbreviation attribute. Create a file
stats.config and add the appropriate XML. Below is an excerpt from
Programmatically Accessing the State Information
With the information in the XML file, the next step was to be able to programmatically access it. I decided to "mimic" the data in the XML file and create a class to store the structure of a state. This class,
State, contains three properties:
Name- returns the full name of the state.
Abbreviation- returns the state's abbreviation.
FullAndAbbrev- returns the full name and abbreviation, like: "Full Name (Abbreviation)". (The reason I chose to add this property was so that when binding the state information to a DropDownList the DropDownList's
DataTextFieldcould be set to this property, thereby displaying both the full name and abbreviation of the state in the DropDownList's text.)
The task that I was now faced with was getting the data out of the XML file and back in terms of a
class instance. To accomplish this I created a
StateManager module with public methods
The first method returns an array of
State objects. The second two methods I used so that I could store
values in one format in a database and be able to switch to the other format in my application, if necessary. That is,
I might have saved a state by its abbreviation in a database and I want to get its full name. I would call
getStateByAbbreviation, passing in the stored abbreviation, and would get back a
object that I could then work with. The last two methods are used to determine if and what errors have occurred.
getErrors returns an ArrayList of
Because file I/O is expensive in terms of system resources, I decided that once an object was requested I would store it in the Cache. When inserting an item into the Cache object you can make it dependent on an external file, meaning that the item is automatically evicted from the Cache when the dependent file is changed. This is ideal for my application, since I can cache the XML data until the underlying XML file changes. (For more information on caching options in ASP.NET be sure to read: Caching with ASP.NET.)
To create this
StateManager module create a file in your Project called
and add the following code:
StateManager Module in an Application
To use the
StateManagermodule in a .NET application start by creating a
StateManager.vbfile in your Visual Studio .NET Project and add the code above, as well as the code for the
Stateclass in a
State.vbfile. Next, add the
states.configfile. If you are wanting to use this in a WinForms application, place the
states.configfile in the application's
\bindirectory; if you're using an ASP.NET Web application, place the
states.configfile in the Web application's root directory.
StateManager is a module, you can use its methods without creating a class instance. This
first code snippet shows how to get back the abbreviation from a state knowing that the full state name is "Virginia":
This next example shows how to get all of the states, and enumerate through them in a
Finally, here's an example of using a databound DropDownList to display the states. In the Web page's HTML portion add a DropDownList like so:
Then, in the code-behind class's
Page_Load event handler you can bind the state data to the DropDownList:
In this article we examined a technique for storing state and province data in an XML file. We saw how to extract the XML data using a
StateManagermodule. Before wrapping things up, let's take a look at some of the pros and cons of this approach. First, the pros:
- Changes to the underlying states/province data are automatic and don't require a recompile - Deployments to multiple environments are easier, as is maintaining the code.
- Switching back and forth between using names and abbreviations is easy
And now, some of the cons:
- Data Not Sorted - The
Stateobjects in the order they appear in the XML file. (If you need to sort the results retrieved, you can use the
Array.Sort()method. For more information on
Array.Sort()be sure to read Sorting an Array Using
- Case Sensitivity - The
getStateByAbbreviationmethods are case sensitive; therefore, if the parameter doesn’t match the case of the attribute in the XML, the application won't retrieve anything.
An improvement on this code would be to add country information to the XML document, so that a page developer could retrieve the states just from a particular country (as opposed to all of the states/provinces in the XML file). Feel free to use the code presented in this article however you see fit. If you make any improvements on the code, or have further ideas for enhancements, please don't hesitate to contact me!
About the Author
Rachael Schoenbaum is a developer specializing in ASP and VB.NET, ASP/Visual Basic, SQL Server, XML, and related technologies. She consults for Lucidea and has been programming since 1999.