Java XML

Es gibt zwei Unterschiedliche Ansätze im in Java XML zu bearbeiten, dom4j und SAX.

Java XML dom4j

So schreibt man in Java eine XML Datei mit dom4j. Dabei wird der komplette Inhalt in ein Objekt gepackt und am Ende in XML umgewandelt.

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

Document document = DocumentHelper.createDocument();
Element root = document.addElement(“foo“);
for(...)
{
  Element node=root.addElement(name);
  node.addText(12345);
}

String xmlString=document.asXML();

Java XML SAX

So liest man inJava eine XML mit SAX. Dabei definiert man Methoden die während dem Lesen der XML Datei aufgerufen werden, z.B. wenn ein sich öffnendes XML Element gefunden wird.

Als erstes eine Hilfklasse, in die wir ein XML Element speichern können

public class MyElement
{
    private String  name;
    private String  content;
    MyElement       father;

    /**
     * @param pName
     */

    public MyElement(String pName) {
        this.name=pName;
    }

    /**
     * @return the father
     */

    public MyElement getFather()
    {
        return father;
    }

    /**
     * @param father the father to set
     */

    public void setFather(MyElement father)
    {
        this.father = father;
    }

    /**
     * @param pContent
     */

    public void addContent(String pContent) {
        content=""+pContent;
    }

    /**
     * @return the name
     */

    public String getName()
    {
        return name;
    }

    /**
     * @return the content
     */

    public String getContent()
    {
        return content;
    }

    /* (non-Javadoc)
     * @see java.lang.Object#toString()
     */

    @Override
    public String toString()
    {
        return "[" + name + "]" + content + "[/"+name+"]";
        //return name;
    }

}

Dann die eigentliche Handler Klasse. Diese enthält die Methoden, die aufgerufen werden sollen. Sie merkt sich dabei alle XML Elemente in der Hilfsklasse

import java.util.Stack;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

/**
* @author Thorsten Gunkel (GUT)
*
* This classes helps SAX to parse an XML document.
* Whenever an XML element is opened, closed or
* data is read one of the corresponding methods is
* called.
*
*/

public abstract class MyXMLHandler extends DefaultHandler
{
    Logger logger=LoggerFactory.getLogger(MyXMLHandler.class);

    /** Stack to remember which element have been opened */
    private Stack<MyElement> elements;  

    /**
     * Constructor
     */

    public MyXMLHandler()
    {
        super();
        elements=new Stack<MyElement>();
    }

    /* (non-Javadoc)
     * @see org.xml.sax.helpers.DefaultHandler#startDocument()
     */

    @Override
    public void startDocument() throws SAXException
    {
        logger.debug("Start to handle new document");
    }

    /* (non-Javadoc)
     * @see org.xml.sax.helpers.DefaultHandler#endDocument()
     */

    @Override
    public void endDocument() throws SAXException
    {
        logger.debug("Stop to handle document");
    }

    /* (non-Javadoc)
     * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
     */

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
    {      
        logger.trace("Start of XML element: "+qName);
        MyElement e=new MyElement(qName);
        if(elements.size()>0)
        {
            MyElement father=elements.peek();
            e.setFather(father);
        }
        elements.push(e);
        newElementStarted(e);
    }

    /**
     * Overwrite this for every XML file you
     * want to parse, it is called every time a new element
     * has been found. New elements are not yet complete
     * so you may decide to do nothing in here
     * @param pElment New and incomplete element
     */

    protected abstract void newElementStarted(MyElement pElment);

    /* (non-Javadoc)
     * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
     */

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException
    {
        logger.trace("End of XML element: "+qName);
        MyElement e=elements.pop();
        if(!e.getName().equals(qName)) {
            elements.add(e);
            throw new SAXException("Found closing element "+qName+" but expected element "+e.getName()+" to be closed.");
        }
        logger.debug("Finished element: "+e);
        newElementFinished(e);
    }

    /**
     * Overwrite this for every XML file you
     * want to parse, it is called every time an
     * element has been closed, this are the
     * complete elements, do something with
     * it
     *
     * @param pElment Finished and complete element
     */

    protected abstract void newElementFinished(MyElement pElment);

    /* (non-Javadoc)
     * @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int)
     */

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException
    {
        String value=new String(ch, start, length);
        logger.trace("Read of data: "+value);
        MyElement e=elements.peek();
        e.addContent(value);
    }

}

Und mit SAX werden diese Methoden dann passend aufgerufen

URL url=BreachXMLServer.class.getClassLoader().getResource("MyXMLInputFile.xml");
String file=url.getFile();
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();

MyXMLHandler h=new MyXMLHandler_ForThisInputFile();      
saxParser.parse(file, h);