Using JDOM to map an xml to a POJO bean

I am using the same xml I used earlier in the blog to map it to the same POJO class I used earlier but this time using a DOM parser. Refer to http://cuppajavamattiz.com/2009/03/19/using-a-sax-parser-to-map-an-xml-to-a-pojo-bean/ for pojo code and source xml.

JDOM has a good API that helps you do lot of stuff on XML files.

Download jdom from the web and remember to put the following jars on your classpath:
xml-apis.jar
xerces.jar
xalan.jar
saxpath.jar
jdom.jar
jaxen-jdom.jar
jaxen-core.jar
These jars are available in the jdom installation.

ElementMapper.java

package com.mattiz.dom.reader;
 
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
 
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.xpath.XPath;
 
public class ElementMapper {
    Document doc;
 
    SAXBuilder builder;
 
    public ElementMapper() throws Exception {
        try {
            builder = new SAXBuilder();
            // disabling xml validation
            builder.setValidation(false);
            builder.setIgnoringElementContentWhitespace(true);
            doc = builder.build(new File("mapper.xml"));
        } catch (JDOMException e) {
            e.printStackTrace();
            throw new Exception(e.getMessage());
        } catch (IOException e) {
            e.printStackTrace();
            throw new Exception(e.getMessage());
        }
    }
 
    private ArrayList getXMLData() throws Exception {
        ArrayList elementsVOArrList = new ArrayList();
        try {
            List ElementSetList = ((List) XPath
                    .selectNodes(doc, "//ElementSet"));
            for (int i = 0; i < ElementSetList.size(); i++) {
                Element elementNode = (Element) ElementSetList.get(i);
                // get children of this parent
                List elementList = (elementNode)
                        .getChildren("Element");
                // iterate over list of list
                ElementsVO elementsVO = null;
                for (Element element : elementList) {
                    elementsVO = new ElementsVO();
                    elementsVO.setGroup(elementNode.getAttributeValue("group"));
                    // get ChemicalSymbol child
                    Element ChemicalSymbolSibling = element
                            .getChild("ChemicalSymbol");
                    elementsVO.setLatinName(ChemicalSymbolSibling.getAttribute(
                            "latin").getValue());
                    // get value of ChemicalSymbol element
                    String chemicalSymbol = ((Element) ChemicalSymbolSibling)
                            .getValue();
                    // get ChemicalName child
                    Element ChemicalNameSibling = element
                            .getChild("ChemicalName");
                    // get value of ChemicalName element
                    String chemicalName = ((Element) ChemicalNameSibling)
                            .getValue();
                    // setting to valueobject
                    elementsVO.setChemicalSymbol(chemicalSymbol);
                    elementsVO.setChemicalName(chemicalName);
                    // add to arraylist
                    elementsVOArrList.add(elementsVO);
                }// for
            }// for
        } catch (Exception ex) {
            throw new Exception();
        }
        return elementsVOArrList;
    }
 
    public static void main(String args[]) {
        try {
            ElementMapper elmapper = new ElementMapper();
            List elementsList = elmapper.getXMLData();
            for (ElementsVO vo : elementsList) {
                System.out.print("  GROUP IS " + vo.getGroup());
                System.out.print("  CHEMICAL NAME IS " + vo.getChemicalName());
                System.out.print("  CHEMICAL SYMBOL IS "
                        + vo.getChemicalSymbol());
                System.out.println(" LATIN NAME IS " + vo.getLatinName());
                System.out.println("************");
            }
        } catch (Exception e) {
        }
    }
}

In both the parser examples the output is similar:

GROUP IS Reactive Elements  CHEMICAL NAME IS Sodium  CHEMICAL SYMBOL IS Na LATIN NAME IS Natrium
************
GROUP IS Reactive Elements  CHEMICAL NAME IS Potassium  CHEMICAL SYMBOL IS K LATIN NAME IS Kalium
************
GROUP IS Metals  CHEMICAL NAME IS Antimony  CHEMICAL SYMBOL IS Sb LATIN NAME IS Stibium
************
GROUP IS Metals  CHEMICAL NAME IS Copper  CHEMICAL SYMBOL IS Cu LATIN NAME IS Cuprum
************
GROUP IS Metals  CHEMICAL NAME IS Tin  CHEMICAL SYMBOL IS Sn LATIN NAME IS Stannum
************

Using a SAX parser to map an XML to a POJO bean

I am using the SAX parser which comes bundled with the jdk. I am using jdk1.5 but without the enhanced loop I have used below it would work as well with jdk1.4
Remember a SAX parser is lighter on memory and is faster, but a bit more complicated to code.

So here goes:

SaxMain.java The main class

package com.mattiz.sax.reader;

import java.io.IOException;
import java.util.ArrayList;

import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;

public class SaxMain {

	public static void main(String args[]) {
		try {
			XMLReader parser = XMLReaderFactory.createXMLReader();
			DefaultHandler saxHandler = new SaxHandler();
			parser.setContentHandler(saxHandler);
			parser.parse("mapper.xml");
			parser = null;
			ArrayList elArray = ((SaxHandler) saxHandler)
					.getElementArray();
			for (ElementsVO a : elArray) {
				System.out.print(" Group is " + a.getGroup());
				System.out.print(" Chemical Name is " + a.getChemicalName());
				System.out
						.print(" Chemical Symbol is " + a.getChemicalSymbol());
				System.out.print(" Latin Name is " + a.getLatinName());
				System.out.println("");
				System.out.println("**********");
			}
		} catch (SAXException e) {
			// TODO
			e.printStackTrace();
		} catch (IOException e) {
			// TODO
			e.printStackTrace();
		}
	}
}

SaxHandler.java Here is where the parsing is done:

package com.mattiz.sax.reader;
 
import java.util.ArrayList;
 
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
 
public class SaxHandler extends DefaultHandler {
 
    private boolean insideChemicalSymbol = false;
 
    private boolean insideChemicalName = false;
 
    private String chemicalSymbol = "";
 
    private String chemicalName = "";
 
    private String group = "";
 
    private String latin = "";
 
    private ArrayList elementArray = new ArrayList();
 
    public void startElement(String uri, String localName, String element_name,
            Attributes attributes) throws SAXException {
        if (localName.equals("ElementSet")) {
            int length = attributes.getLength();
            // Each attribute
            for (int i = 0; i < length; i++) {
                // Get names and values to each attribute
                String name = attributes.getQName(i);
                if (name.equals("group")) {
                    group = attributes.getValue(i);
                }
            }
        }
        if (localName.equals("ChemicalSymbol")) {
            insideChemicalSymbol = true;
            int length = attributes.getLength();
            // Each attribute
            for (int i = 0; i < length; i++) {
                // Get names and values to each attribute
                String name = attributes.getQName(i);
                if (name.equals("latin")) {
                    latin = attributes.getValue(i);
                }
            }
        }
        if (localName.equals("ChemicalName")) {
            insideChemicalName = true;
        }
    }
 
    public void characters(char[] ch, int start, int len) throws SAXException {
 
        if (insideChemicalSymbol) {
            chemicalSymbol = (new String(ch, start, len)).trim();
        }
        if (insideChemicalName) {
            chemicalName = (new String(ch, start, len)).trim();
        }
    }
 
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        if (localName.equals("ChemicalSymbol")) {
            insideChemicalSymbol = false;
        }
        if (localName.equals("ChemicalName")) {
            insideChemicalName = false;
        }
        if (localName.equals("Element")) {
            ElementsVO elVO = new ElementsVO();
            elVO.setGroup(group);
            elVO.setChemicalName(chemicalName);
            elVO.setChemicalSymbol(chemicalSymbol);
            elVO.setLatinName(latin);
            elementArray.add(elVO);
        }
    }
 
    public ArrayList getElementArray() {
        return elementArray;
    }
}

ElementsVO.java that maps to the xml

package com.mattiz.sax.reader;

public class ElementsVO {

	private String group;
	private String chemicalSymbol;
	private String chemicalName;
	private String latinName;

	public String getLatinName() {
		return latinName;
	}
	public void setLatinName(String latinName) {
		this.latinName = latinName;
	}
	public String getChemicalName() {
		return chemicalName;
	}

	public void setChemicalName(String chemicalName) {
		this.chemicalName = chemicalName;
	}
	public String getChemicalSymbol() {
		return chemicalSymbol;
	}
	public void setChemicalSymbol(String chemicalSymbol) {
		this.chemicalSymbol = chemicalSymbol;
	}

	public String getGroup() {
		return group;
	}
	public void setGroup(String group) {
		this.group = group;
	}
}

mapper.xml
The xml to be mapped to the bean:

<?xml version="1.0" encoding="UTF-8"?>
<Root>
    <ElementSet group="Reactive Elements">
        <Element>
            <ChemicalSymbol latin="Natrium">Na</ChemicalSymbol>
            <ChemicalName>Sodium</ChemicalName>
        </Element>
        <Element>
            <ChemicalSymbol latin="Kalium">K</ChemicalSymbol>
            <ChemicalName>Potassium</ChemicalName>
        </Element>
    </ElementSet>
    <ElementSet group="Metals">
        <Element>
            <ChemicalSymbol latin="Stibium">Sb</ChemicalSymbol>
            <ChemicalName>Antimony</ChemicalName>
        </Element>
        <Element>
            <ChemicalSymbol latin="Cuprum">Cu</ChemicalSymbol>
            <ChemicalName>Copper</ChemicalName>
        </Element>
        <Element>
            <ChemicalSymbol latin="Stannum">Sn</ChemicalSymbol>
            <ChemicalName>Tin</ChemicalName>
        </Element>
    </ElementSet>
</Root>