What is the best/simplest way to read in an XML file in Java application?

JavaXmlFile

Java Problem Overview


Currently our Java application uses the values held within a tab delimited *.cfg file. We need to change this application so that it now uses an XML file.

What is the best/simplest library to use in order to read in values from this file?

Java Solutions


Solution 1 - Java

There are of course a lot of good solutions based on what you need. If it is just configuration, you should have a look at Jakarta commons-configuration and commons-digester.

You could always use the standard JDK method of getting a document :

import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;

[...]

File file = new File("some/path");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document document = db.parse(file);

Solution 2 - Java

XML Code:

<?xml version="1.0"?>
<company>
	<staff id="1001">
		<firstname>yong</firstname>
		<lastname>mook kim</lastname>
		<nickname>mkyong</nickname>
		<salary>100000</salary>
	</staff>
	<staff id="2001">
		<firstname>low</firstname>
		<lastname>yin fong</lastname>
		<nickname>fong fong</nickname>
		<salary>200000</salary>
	</staff>
</company>

Java Code:

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import java.io.File;
 
public class ReadXMLFile {
 
  public static void main(String argv[]) {
    try {
	File fXmlFile = new File("/Users/mkyong/staff.xml");
	DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
	DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
	Document doc = dBuilder.parse(fXmlFile);
	doc.getDocumentElement().normalize();
 
	System.out.println("Root element :" + doc.getDocumentElement().getNodeName());
	NodeList nList = doc.getElementsByTagName("staff");
	System.out.println("----------------------------");
 
	for (int temp = 0; temp < nList.getLength(); temp++) {
		Node nNode = nList.item(temp);
		System.out.println("\nCurrent Element :" + nNode.getNodeName());
		if (nNode.getNodeType() == Node.ELEMENT_NODE) {
			Element eElement = (Element) nNode;
			System.out.println("Staff id : "
                               + eElement.getAttribute("id"));
			System.out.println("First Name : "
                               + eElement.getElementsByTagName("firstname")
                                 .item(0).getTextContent());
			System.out.println("Last Name : "
                               + eElement.getElementsByTagName("lastname")
                                 .item(0).getTextContent());
			System.out.println("Nick Name : "
                               + eElement.getElementsByTagName("nickname")
                                 .item(0).getTextContent());
			System.out.println("Salary : "
                               + eElement.getElementsByTagName("salary")
                                 .item(0).getTextContent());
		}
	}
    } catch (Exception e) {
	e.printStackTrace();
    }
  }
}

Output:

----------------

Root element :company
----------------------------
 
Current Element :staff
Staff id : 1001
First Name : yong
Last Name : mook kim
Nick Name : mkyong
Salary : 100000
 
Current Element :staff
Staff id : 2001
First Name : low
Last Name : yin fong
Nick Name : fong fong
Salary : 200000

I recommended you reading this: Normalization in DOM parsing with java - how does it work?

Example source.

Solution 3 - Java

> What is the best/simplest library to > use in order to read in values from > this file?

As you're asking for the simplest library, I feel obliged to add an approach quite different to that in Guillaume's top-voted answer. (Of the other answers, sjbotha's JDOM mention is closest to what I suggest).

I've come to think that for XML handling in Java, using the standard JDK tools is certainly not the simplest way, and that only in some circumstances (such as not being able to use 3rd party libraries, for some reason) it is the best way.

Instead, consider using a good XML library, such as XOM. Here's how to read an XML file into a nu.xom.Document object:

import nu.xom.Builder;
import nu.xom.Document;
import java.io.File;

[...]

File file = new File("some/path");
Document document = new Builder().build(file);

So, this was just a little bit simpler, as reading the file into org.w3c.dom.Document wasn't very complicated either, in the "pure JDK" approach. But the advantages of using a good library only start here! Whatever you're doing with your XML, you'll often get away with much simpler solutions, and less of your own code to maintain, when using a library like XOM. As examples, consider this vs. this, or this vs. this, or this post containing both XOM and W3C DOM examples.

Others will provide counter-arguments (like these) for why sticking to Java's standard XML APIs may be worth it - these probably have merit, at least in some cases, although personally I don't subscribe to all of them. In any case, when choosing one way or the other, it's good to be aware of both sides of the story.

(This answer is part of my evaluation of XOM, which is a strong contender in my quest for finding the best Java XML library to replace dom4j.)

Solution 4 - Java

Is there a particular reason you have chosen XML config files? I have done XML configs in the past, and they have often turned out to be more of a headache than anything else.

I guess the real question is whether using something like the Preferences API might work better in your situation.

Reasons to use the Preferences API over a roll-your-own XML solution:

  • Avoids typical XML ugliness (DocumentFactory, etc), along with avoiding 3rd party libraries to provide the XML backend

  • Built in support for default values (no special handling required for missing/corrupt/invalid entries)

  • No need to sanitize values for XML storage (CDATA wrapping, etc)

  • Guaranteed status of the backing store (no need to constantly write XML out to disk)

  • Backing store is configurable (file on disk, LDAP, etc.)

  • Multi-threaded access to all preferences for free

Solution 5 - Java

JAXB is simple to use and is included in Java 6 SE. With JAXB, or other XML data binding such as Simple, you don't have to handle the XML yourself, most of the work is done by the library. The basic usage is to add annotation to your existing POJO. These annotation are then used to generate an XML Schema for you data and also when reading/writing your data from/to a file.

Solution 6 - Java

Look into JAXB.

Solution 7 - Java

I've only used jdom. It's pretty easy.

Go here for documentation and to download it: http://www.jdom.org/

If you have a very very large document then it's better not to read it all into memory, but use a SAX parser which calls your methods as it hits certain tags and attributes. You have to then create a state machine to deal with the incoming calls.

Solution 8 - Java

The simplest by far will be Simple http://simple.sourceforge.net, you only need to annotate a single object like so

@Root
public class Entry {

   @Attribute
   private String a
   @Attribute
   private int b;
   @Element
   private Date c;

   public String getSomething() {
      return a;
   }
} 

@Root
public class Configuration {

   @ElementList(inline=true)
   private List<Entry> entries;

   public List<Entry> getEntries() { 
      return entries;
   }
}

Then all you have to do to read the whole file is specify the location and it will parse and populate the annotated POJO's. This will do all the type conversions and validation. You can also annotate for persister callbacks if required. Reading it can be done like so.

Serializer serializer = new Persister();
Configuration configuraiton = serializer.read(Configuration.class, fileLocation);

Solution 9 - Java

Depending on your application and the scope of the cfg file, a properties file might be the easiest. Sure it isn't as elegant as xml but it certainly easier.

Solution 10 - Java

Use java.beans.XMLDecoder, part of core Java SE since 1.4.

XMLDecoder input = new XMLDecoder(new FileInputStream("some/path.xml"));
MyConfig config = (MyConfig) input.readObject();
input.close();

It's easy to write the configuration files by hand, or use the corresponding XMLEncoder with some setup to write new objects at run-time.

Solution 11 - Java

This is what I use. http://marketmovers.blogspot.com/2014/02/the-easy-way-to-read-xml-in-java.html It sits on top of the standard JDK tools, so if it's missing some feature you can always use the JDK version.

This really makes things easier for me. It's especially nice when I'm reading a config file that was saved by and older version of the software, or was manually edited by a user. It's very robust and won't throw an exception if some data is not exactly in the format you expect.

Solution 12 - Java

Here's a really simple API that I created for reading simple XML files in Java. It's incredibly simple and easy to use. Hope it's useful for you.

http://argonrain.wordpress.com/2009/10/27/000/

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionrmccView Question on Stackoverflow
Solution 1 - JavaGuillaumeView Answer on Stackoverflow
Solution 2 - JavaRan AdlerView Answer on Stackoverflow
Solution 3 - JavaJonikView Answer on Stackoverflow
Solution 4 - JavaJames Van HuisView Answer on Stackoverflow
Solution 5 - JavaPierre BuyleView Answer on Stackoverflow
Solution 6 - JavacletusView Answer on Stackoverflow
Solution 7 - JavaSarel BothaView Answer on Stackoverflow
Solution 8 - Javang.View Answer on Stackoverflow
Solution 9 - JavatmeisenhView Answer on Stackoverflow
Solution 10 - JavaericksonView Answer on Stackoverflow
Solution 11 - JavaTrade-Ideas PhilipView Answer on Stackoverflow
Solution 12 - JavaChrisView Answer on Stackoverflow