Parsing and updating xml using SAX parser in java

3.9k views Asked by At

I have an xml file with similar tags ->

<properties>
   <definition>
      <name>IP</name>
      <description></description>
      <defaultValue>10.1.1.1</defaultValue>
   </definition>
   <definition>
      <name>Name</name>
      <description></description>
      <defaultValue>MyName</defaultValue>
   </definition>
   <definition>
      <name>Environment</name>
      <description></description>
      <defaultValue>Production</defaultValue>
   </definition>
</properties>

I want to update the default value of the definition with name : Environment.

Is it possible to do that using SAX parser?

Can you please point me to proper documentation?

So far I have parsed the document but when I update defaultValue, it updates all defaultValues. I dont know how to parse the exact default value tag.

1

There are 1 answers

1
stringy05 On BEST ANSWER

Anything is possible with SAX, it's just waaaaay harder than it has to be. It's pretty old school and there are many easier ways to do this (JAXB, XQuery, XPath, DOM etc ).

That said lets do it with SAX.

It sounds like the problem you are having is that you are not tracking the state of your progress through the document. SAX simply works by making the callbacks when it stumbles across an event within the document

This is a fairly crude way of parsing the doc and updating the relevant node using SAX. Basically I am checking when we hit a element with the value you want to update (Environment) and setting a flag so that when we get to the contents of the defaultValue node, the characters callback lets me remove the existing value and replace it with the new value.

import java.io.StringReader;
import java.util.Arrays;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

public class Q26897496 extends DefaultHandler {

    public static String xmlDoc = "<?xml version='1.0'?>"   
            + "<properties>"
            + "   <definition>" 
            + "      <name>IP</name>"  
            + "      <description></description>"
            + "      <defaultValue>10.1.1.1</defaultValue>"
            + "   </definition>" 
            + "   <definition>"
            + "      <name>Name</name>" 
            + "      <description></description>"
            + "      <defaultValue>MyName</defaultValue>" 
            + "   </definition>"
            + "   <definition>" 
            + "      <name>Environment</name>"
            + "      <description></description>"
            + "      <defaultValue>Production</defaultValue>"
            + "   </definition>" 
            + "</properties>";


    String elementName;
    boolean mark = false;
    char[] updatedDoc;

    public static void main(String[] args) {

        Q26897496 q = new Q26897496();
        try {
            q.parse();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public Q26897496() {

    }

    public void parse() throws Exception {
        SAXParserFactory spf = SAXParserFactory.newInstance();
        spf.setNamespaceAware(true);
        SAXParser saxParser = spf.newSAXParser();
        XMLReader xml = saxParser.getXMLReader();
        xml.setContentHandler(this);
        xml.parse(new InputSource(new StringReader(xmlDoc)));

        System.out.println("new xml: \n" + new String(updatedDoc));
    }

    @Override
    public void startDocument() throws SAXException {
        System.out.println("starting");

    }

    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        this.elementName = localName;
    }

    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException {

        String value = new String(ch).substring(start, start + length);
        if (elementName.equals("name")) {
            if (value.equals("Environment")) {
                this.mark = true;
            }
        }

        if (elementName.equals("defaultValue") && mark == true) {
            // update
            String tmpDoc = new String(ch);
            String leading = tmpDoc.substring(0, start);
            String trailing = tmpDoc.substring(start + length, tmpDoc.length());
            this.updatedDoc = (leading + "NewValueForDefaulValue" + trailing).toCharArray();
            mark = false;
        }
    }
}