Saliceran
Saliceran

Reputation: 350

SAX XML Parser throwing Null Pointer Exception

I'm trying to write an SAX XML Parser in Java and I keep getting a null pointer exception that I can't seem to figure out how to fix. Here is the stack trace:

Exception in thread "main" java.lang.NullPointerException
    at SAXParserExample.endElement(SAXParserExample.java:91)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.endElement(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanEndElement(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
    at javax.xml.parsers.SAXParser.parse(Unknown Source)
    at javax.xml.parsers.SAXParser.parse(Unknown Source)
    at SAXParserExample.parseDocument(SAXParserExample.java:43)
    at SAXParserExample.runExample(SAXParserExample.java:29)
    at SAXParserExample.main(SAXParserExample.java:107)

Here is the main class for the SAX Parser:

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

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

import org.xml.sax.SAXException;

import org.xml.sax.helpers.DefaultHandler;

public class SAXParserExample extends DefaultHandler{

    List<DataRow> myFiles;

    private String tempVal;

    //to maintain context
    private DataRow tempFile;


    public SAXParserExample(){
        myFiles = new ArrayList<DataRow>();
    }

    public void runExample() {
        parseDocument();
        printData();
    }

    private void parseDocument() {

        //get a factory
        SAXParserFactory spf = SAXParserFactory.newInstance();
        try {

            //get a new instance of parser
            SAXParser sp = spf.newSAXParser();

            //parse the file and also register this class for call backs
            sp.parse("./src/filelist.xml", this);

        }catch(SAXException se) {
            se.printStackTrace();
        }catch(ParserConfigurationException pce) {
            pce.printStackTrace();
        }catch(IOException ie) {
            ie.printStackTrace();
        }
    }

    /**
     * Iterate through the list and print
     * the contents
     */
    private void printData(){

        System.out.println("No of Files '" + myFiles.size() + "'.");

        Iterator<DataRow> it = myFiles.iterator();
        while(it.hasNext()) {
            System.out.println(it.next().toString());
        }
    }


    //Event Handlers
    public void startElement(String uri, String localName, String qName) throws SAXException {
        //reset
        tempVal = "";
        if(qName.equalsIgnoreCase("DATAROW")) {
            //create a new instance of Datarow
            tempFile = new DataRow();
        }
    }


    public void characters(char[] ch, int start, int length) throws SAXException {
        tempVal = new String(ch,start,length);
    }

    public void endElement(String uri, String localName, String qName) throws SAXException {

        if(qName.equalsIgnoreCase("DATAROW")) {
            //add it to the list
            myFiles.add(tempFile);

        }else if (qName.equalsIgnoreCase("ID")) {
            tempFile.setID(Integer.parseInt(tempVal));
        }else if (qName.equalsIgnoreCase("FILENAME")) {
            tempFile.setFileName(tempVal);
        }else if (qName.equalsIgnoreCase("SEARCHKEY")) {
            tempFile.setSearchKey(tempVal);
        }else if (qName.equalsIgnoreCase("DATEADDED")) {
            tempFile.setDateAdded(tempVal);
        }else if (qName.equalsIgnoreCase("APPLICATIONID")) {
            tempFile.setApplicationID(tempVal);
        }else if (qName.equalsIgnoreCase("DISPLAYFILENAME")) {
            tempFile.setDisplayFileName(tempVal);
        }
    }

    public static void main(String[] args){
        SAXParserExample spe = new SAXParserExample();
        spe.runExample();
    }
}

Here is the DataRow class used in the main class:

public class DataRow {

    private String fileName = "", searchKey = "", dateAdded = "", applicationID = "", displayFileName = "";

    private int id = 0;

    public DataRow(){

    }

    public DataRow(int id, String fileName, String searchKey, String dateAdded, String applicationID, String displayFileName) {
        this.id  = id;
        this.fileName = fileName;
        this.searchKey = searchKey;
        this.dateAdded = dateAdded;
        this.applicationID = applicationID;
        this.displayFileName = displayFileName;

    }
    public String getFileName() {
        return fileName;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    public int getID() {
        return id;
    }

    public void setID(int id) {
        this.id = id;
    }

    public String getSearchKey() {
        return searchKey;
    }

    public void setSearchKey(String searchKey) {
        this.searchKey = searchKey;
    }

    public String getDateAdded() {
        return dateAdded;
    }

    public void setDateAdded(String dateAdded) {
        this.dateAdded = dateAdded;
    }   

    public String getApplicationID() {
        return applicationID;
    }

    public void setApplicationID(String applicationID) {
        this.applicationID = applicationID;
    }

    public String getDisplayFileName() {
        return displayFileName;
    }

    public void setDisplayFileName(String displayFileName) {
        this.displayFileName = displayFileName;
    }

    public String toString() {
        StringBuffer sb = new StringBuffer();
        sb.append("File Details - ");
        sb.append("ID:" + getID());
        sb.append(", ");
        sb.append("Filename:" + getFileName());
        sb.append(", ");
        sb.append("Search Key:" + getSearchKey());
        sb.append(", ");
        sb.append("Date Added:" + getDateAdded());
        sb.append(", ");
        sb.append("Application ID:" + getApplicationID());
        sb.append(", ");
        sb.append("Display Filename:" + getDisplayFileName());
        sb.append(".");

        return sb.toString();
    }
}

And here is the XML file I'm attempting to parse:

<DATAROW><ID>61</ID><FILENAME>TestFile.txt</FILENAME><SEARCHKEY>12345</SEARCHKEY><DATEADDED>2012-1-6 9.12.32.0</DATEADDED><APPLICATIONID>PCIS</APPLICATIONID><DISPLAYFILENAME>TestFile.txt</DISPLAYFILENAME></DATAROW><DATAROW><ID>44</ID><FILENAME>TestFile.txt</FILENAME><SEARCHKEY>12345</SEARCHKEY><DATEADDED>2012-2-5 14.39.50.0</DATEADDED><APPLICATIONID>PCIS</APPLICATIONID><DISPLAYFILENAME>TestFile.txt</DISPLAYFILENAME></DATAROW>

The XML file is formatted that way because eventually it's going to be parsing metadata return from a database in the form of a single string.

Upvotes: 0

Views: 9749

Answers (4)

user1357786
user1357786

Reputation: 31

Your override function

public void startElement(String uri, String localName, String qName) throws SAXException{...}

should be

public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException{...}

change it to as following,it works well

public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException {
        //reset
        tempVal = "";
        if(qName.equalsIgnoreCase("DATAROW")) {
            //create a new instance of Datarow
            tempFile = new DataRow();
        }
    }

Upvotes: 0

Tudor
Tudor

Reputation: 62439

Ok, I've bothered to count the lines and 91 is this line:

tempFile.setID(Integer.parseInt(tempVal));

so tempFile is null.

Upvotes: 4

Seramme
Seramme

Reputation: 1350

I haven't used SAX for quite some time, so may be wrong, but my guess is that that you should use the localName, not the qname here, since there are no qualified names (ie. the names that have some namespace like 'namespace:name') in your XML. Therefore, most probably the qname provided is null and, since you access it for comparison, you get an NPE.

According to the javadoc (http://docs.oracle.com/javase/1.4.2/docs/api/org/xml/sax/helpers/DefaultHandler.html#endElement(java.lang.String, java.lang.String, java.lang.String) ), the qname provided may be empty if it is not available in the XML document.

Upvotes: 2

Bryan Kyle
Bryan Kyle

Reputation: 13761

From the exception you can tell that you're attempting to dereference a variable whose value is null. Why not look at line 91 and print out all of the variables that are being used to see which are null. My guess is that tempFile is never assigned which means its null on line 91.

Upvotes: 3

Related Questions