2012-01-06 45 views
0

我想寫一個SAX XML解析器在Java中,我不斷得到一個空指針異常,我似乎無法弄清楚如何解決。這裏是堆棧跟蹤:SAX XML解析器拋出空指針異常

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) 

下面是SAX解析器主類:

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(); 
    } 
} 

下面是在主類中使用的DataRow類:

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(); 
    } 
} 

這裏是我試圖解析的XML文件:

<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> 

XML文件的格式如此,因爲最終它將以單個字符串的形式解析數據庫的元數據返回。

+0

哪一個是線91? – Tudor 2012-01-06 16:35:56

回答

2

我沒有使用SAX很長一段時間,所以可能是錯誤的,但我的猜測是,你應該使用localName,而不是qname,因爲在你的XML中沒有合格的名稱(即名稱空間名稱有'namespace:name')。因此,大多數情況下提供的qname都是null,並且由於您可以訪問它以進行比較,因此您將得到一個NPE。

根據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)),如果在XML文檔中不可用,則提供的qname可能爲空。

4

好吧,我不屑於計數線和91是這一行:

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

所以tempFilenull

+0

myFiles在構造函數中初始化。 – 2012-01-06 16:42:42

3

從異常中可以看出,您試圖取消引用其值爲空的變量。爲什麼不看第91行並打印出所有正在使用的變量來查看哪些變量爲空。我的猜測是,tempFile從來沒有分配,這意味着它的91行上的空。

0

您的覆蓋功能

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

應該

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

將其更改爲如下,它工作得很好

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(); 
     } 
    }