Wednesday, January 14, 2015

XMLMemento: a simpe way to process XML files


Reading and writing simple XML files is a common task nowadays. Java comes with some powerful frameworks like SAX or Xerces to accomplish this task. But sometimes we look for something simpler. Today we will have a look at XMLMemento, a utility class by Eclipse that hides most of the complicated stuff from us.

Source code for this tutorial is available on googlecode as a single zip archive, as a Team Project Set or you can checkout the SVN projects directly. 

Preparations

We will use following XML file for this tutorial
<?xml version="1.0" encoding="UTF-8"?>
<root>
 <project name="org.eclipse.ease">
  <description>EASE is a scripting environment for Eclipse. It allows to
   create, maintain and execute script code in the context of the
   running Eclipse instance.</description>
  <releases>
   <release version="0.1.0" />
   <release version="0.2.0" />
  </releases>
 </project>
 <project name="org.eclipse.tycho">
  <releases>
   <release version="0.16.0" />
   <release version="0.17.0" />
  </releases>
 </project>
</root>

The code samples below use a slightly modified version of XMLMemento. To reuse it more easily in non-Eclipse projects I removed Eclipse specific exceptions, messages and interfaces. If you intend to use XMLMemento within Eclipse, simply stick to the original version contained in the org.eclipse.ui.workbench plugin. For pure Java projects simply copy XMLMemento as it is used in this tutorial.

Step 1: Writing XML

First we need to create a root node. Afterwards we create child nodes and set their attributes.
package com.codeandme.xmlmemento;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import org.eclipse.ui.XMLMemento;

public class WriteXML {

 public static void main(String[] args) {

  XMLMemento rootNode = XMLMemento.createWriteRoot("root");

  // first project
  XMLMemento projectNode = rootNode.createChild("project");
  projectNode.putString("name", "org.eclipse.ease");
  projectNode
  .createChild("description")
  .putTextData(
    "EASE is a scripting environment for Eclipse. It allows to create, maintain and execute script code in the context of the running Eclipse instance.");

  XMLMemento releasesNode = projectNode.createChild("releases");
  releasesNode.createChild("release").putString("version", "0.1.0");
  releasesNode.createChild("release").putString("version", "0.2.0");

  // second project
  projectNode = rootNode.createChild("project");
  projectNode.putString("name", "org.eclipse.tycho");

  releasesNode = projectNode.createChild("releases");
  releasesNode.createChild("release").putString("version", "0.16.0");
  releasesNode.createChild("release").putString("version", "0.17.0");

  // output to console
  System.out.println(rootNode);

  // write to file
  try {
   File tempFile = new File("XML sample.xml");
   FileWriter fileWriter = new FileWriter(tempFile);
   rootNode.save(fileWriter);

  } catch (IOException e) {
   e.printStackTrace();
  }
 }
}
Line 13: create the root node
Line 16: create a child node below root
Line 17: set an attribute on project node
Line 20: set text content of a node
Line 36: serialize XML to String (uses node.toString())
Line 42: write XML to File


Step 2: reading XML

Reading XML is also very easy. Just create a read root and start traversing child elements:
package com.codeandme.xmlmemento;

import java.io.FileReader;

import org.eclipse.ui.XMLMemento;

public class ReadXML {

 public static void main(String[] args) {
  try {
   XMLMemento rootNode = XMLMemento.createReadRoot(new FileReader("XML sample.xml"));

   System.out.println("Projcts:");
   for (XMLMemento node : rootNode.getChildren())
    System.out.println("\t" + node.getString("name"));

   System.out.println("EASE versions:");
   for (XMLMemento node : rootNode.getChildren("project")) {
    if ("org.eclipse.ease".equals(node.getString("name"))) {
     for (XMLMemento versionNode : node.getChild("releases").getChildren("release")) {
      System.out.println("\t" + versionNode.getString("version"));
     }
    }
   }

  } catch (Exception e) {
   e.printStackTrace();
  }
 }
}
LIne 11: parse input and extract the root node
Line 14: iterate over all child nodes
Line 15: read node attribute

No comments:

Post a Comment