Taming Tiger: Loading Properties from XML

Stop the key-value pair insanity

The Properties class is an old favorite, around since the beginning of Java programming time with very few changes. The Tiger release of J2SE enhances this class, which allows you not only to use it to specify key-value pairs on a single line separated by an equal sign, but also to use XML files to load and save those key-value pairs. In this installment of Taming Tiger, John Zukowski demonstrates how to use this updated work horse.

Share:

John Zukowski (jaz@zukowski.net), President, JZ Ventures, Inc.

Author photoJohn Zukowski conducts strategic Java consulting with JZ Ventures, Inc. and is working with SavaJe Technologies to develop a next-generation mobile phone platform. His latest books are Mastering Java 2, J2SE 1.4 (Sybex, April 2002) and Learn Java with JBuilder 6 (Apress, March 2002). Reach him at jaz@zukowski.net.



25 February 2004

Also available in Japanese

J2SE versions prior to 1.5 required you to work directly with the XML parser to load a configuration file and store settings. While it was never difficult, and while the parser is a standard part of the platform, the extra work was a bit of an annoyance. The newly updated java.util.Properties class now offers an easier way to load and store settings for a program: the loadFromXML(InputStream is) and storeToXML(OutputStream os, String comment) methods.

Properties basics

If you aren't familiar with the java.util.Properties class, you use it to store a set of key-value pairs in a file, where the key and value are separated by an equal sign, as shown in Listing 1.

Listing 1. Sample set of properties
foo=bar
fu=baz

Had Listing 1 been loaded into a Properties object, you would then find two keys (foo and fu) and two values (bar for foo and baz for fu). The class supports embedding Unicode strings with \u, but the important thing here is that everything is treated as a String.

Listing 2 shows how to load the properties file and list its current set of keys and values. You just pass an InputStream for the file to the load() method, and each key-value pair is added to the Properties instance. You would then use list() to list all the properties or getProperty() to retrieve an individual one.

Listing 2. Loading properties
import java.util.*;
import java.io.*;

public class LoadSample {
  public static void main(String args[]) throws Exception {
    Properties prop = new Properties();
    FileInputStream fis = 
      new FileInputStream("sample.properties");
    prop.load(fis);
    prop.list(System.out);
    System.out.println("\nThe foo property: " +
        prop.getProperty("foo"));
  }
}

Running the LoadSample program produces the output in Listing 3. Notice that the output of the list() method does not produce the list of key-value pairs in the same order they were in the input file. The Properties class stores the set of pairs in a hashtable (in fact, it is a Hashtable subclass), so there is no guarantee for order.

Listing 3. Output from LoadSample
-- listing properties --
fu=baz
foo=bar

The foo property: bar

XML property files

None of this should be new to you. This is how the Properties class has always worked. What is new, however, is the option of loading a set of properties from an XML file. The DTD for that is shown in Listing 4.

Listing 4. Properties DTD
<?xml version="1.0" encoding="UTF-8"?>
<!-- DTD for properties -->
<!ELEMENT properties ( comment?, entry* ) >
<!ATTLIST properties version CDATA #FIXED "1.0">
<!ELEMENT comment (#PCDATA) >
<!ELEMENT entry (#PCDATA) >
<!ATTLIST entry key CDATA #REQUIRED>

If you're not into reading XML DTDs, this essentially says that wrapped within an outer <properties> tag is a <comment> tag, followed by any number of <entry> tags. For each <entry> tag, there is a key attribute, with the contents of the entry being its value. Listing 5 shows what the XML version of the properties file in Listing 1 would look like.

Listing 5. XML version of the Properties file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>Hi</comment>
<entry key="foo">bar</entry>
<entry key="fu">baz</entry>
</properties>

As Listing 6 shows, reading the XML version of the Properties file isn't much different than reading the older style format.

Listing 6. Reading the XML Properties file
import java.util.*;
import java.io.*;

public class LoadSampleXML {
  public static void main(String args[]) throws Exception {
    Properties prop = new Properties();
    FileInputStream fis =
      new FileInputStream("sampleprops.xml");
    prop.loadFromXML(fis);
    prop.list(System.out);
    System.out.println("\nThe foo property: " +
        prop.getProperty("foo"));
  }
}

A note about resource bundles

While the java.util.Properties class now supports properties files as XML files in addition to key-value pairs, unfortunately, there is no built-in option available to treat a ResourceBundle as an XML file. Yes, a PropertyResourceBundle does use a Properties object to load the bundle; however, the use of the load method is hard-coded into the class, and the newer loadFromXML() method is not used.

Running the program in Listing 6 produces the same output as the original program, which is shown in Listing 2.


Saving XML Properties

The other side of the new Properties capabilities is storing properties to an XML-formatted file. While the store() method will still create a file like that shown in Listing 1, you can now use the new storeToXML() method to create the file shown in Listing 5. Just pass in an OutputStream and a String for the comment and you're done. Listing 7 demonstrates the new storeToXML() method.

Listing 7. Storing Properties as an XML file
import java.util.*;
import java.io.*;

public class StoreXML {
  public static void main(String args[]) throws Exception {
    Properties prop = new Properties();
    prop.setProperty("one-two", "buckle my shoe");
    prop.setProperty("three-four", "shut the door");
    prop.setProperty("five-six", "pick up sticks");
    prop.setProperty("seven-eight", "lay them straight");
    prop.setProperty("nine-ten", "a big, fat hen");
    FileOutputStream fos =
      new FileOutputStream("rhyme.xml");
    prop.storeToXML(fos, "Rhyme");
    fos.close();
  }
}

The output produced from running the program in Listing 7 is shown in Listing 8.

Listing 8. Stored XML file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>Rhyme</comment>
<entry key="seven-eight">lay them straight</entry>
<entry key="five-six">pick up sticks</entry>
<entry key="nine-ten">a big, fat hen</entry>
<entry key="three-four">shut the door</entry>
<entry key="one-two">buckle my shoe</entry>
</properties>

Conclusion

The choice of using an XML file or older-style a=b type file is completely up to you. The older style is certainly lighter weight from a memory perspective. However, pervasiveness of XML, one would expect the XML format to be popular, as it is widely used already, just not by means of the Properties object. The choice is completely up to you. Examine the source for the package private XMLUtils class for additional information about the XML parsing used.


Download

DescriptionNameSize
Code samplej-tiger02254source.zip2KB

Resources

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Java technology on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Java technology
ArticleID=10917
ArticleTitle=Taming Tiger: Loading Properties from XML
publish-date=02252004