2016-05-31 103 views
0

我試圖通過SAX解析器來解析下一個XML文檔:SAX解析器 - NumberFormatException的

<?xml version="1.0" encoding="UTF-8" ?> 

<dance title="foxtrot" id="1"> 

    <type>ballroom</type> 

    <scene>assembly hall</scene> 

    <numberOfDancers>10</numberOfDancers> 

    <music>phonogram</music> 

    <dancers> 
     <dancer>Ivanov Ivan</dancer> 
     <dancer>Petrova Ludmila</dancer> 
    </dancers> 

    <number>22</number> 

</dance> 

它在人物:

if (thisElement.equals("numberOfDancers")) { 
    dance.setNumberOfDancers(new Integer((new String(ch, start, length)))); 
} 

,這就是我得到:

java.lang.NumberFormatException: For input string: " 

    " 
at  java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) 
at java.lang.Integer.parseInt(Integer.java:569) 
at java.lang.Integer.parseInt(Integer.java:615) 
at parsers.SAXParser.characters(SAXParser.java:58) 
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.characters(AbstractSAXParser.java:546) 
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:463) 
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:848) 
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:777) 
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141) 
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213) 
at  com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:643) 
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl.parse(SAXParserImpl.java:327) 
at javax.xml.parsers.SAXParser.parse(SAXParser.java:328) 
at Main.main(Main.java:37) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:498) 
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144) 




Integer.java:569 is next: 
    } else if (firstChar != '+') 
        throw NumberFormatException.forInputString(s); 

問題在哪裏?

+0

要獲得更好的答案,請顯示您的ContentHandler代碼。 –

回答

0

在您的代碼中,您試圖將子字符串new String(ch, start, length)解析爲Integer。 NumberFormatException的只是說,你說話是算數的 - 換行字符不能被解釋爲數字:

java.lang.NumberFormatException: For input string: " 

" 

,如果你在你的XML這樣的事情可能發生這種情況:

... 
<scene>assembly hall</scene> 
<numberOfDancers> 
</numberOfDancers> 
<music>phonogram</music> 
... 

檢查你的XML輸入。

+0

感謝您的回答,但我在標籤之間沒有新行標誌。我的xml文件和我的文章完全一樣。 – savelich

0

變量thisElement中的元素文本與您認爲您當前在xml中的位置無關。從錯誤信息中可以看出,它包含一個帶有換行符的空白字符串,並且該空白字符串可能是當前元素之前的元素文本。

您不會顯示您的內容處理程序或它如何初始化thisElement或您如何跟蹤您在文檔中的位置,這將進一步診斷此位置。

看起來很清楚的是你的字符方法不符合SAX文檔。字符方法可以由解析器每個元素多次調用,直到調用endElement方法時,您不能確定是否具有完整的元素文本。請參閱the Oracle tutorial

解析器不需要一次返回任何特定數量的字符。解析器可以一次返回任何一個字符,最多可以有幾千個字符,並且仍然是符合標準的實現。因此,如果您的應用程序需要處理它所看到的字符,那麼讓characters()方法在java.lang.StringBuffer中累積字符並且僅在確定已找到所有字符時纔對它們進行操作是明智的。

字符方法不應該只是將內容保存在緩衝區中(例如追加到StringBuilder)。檢查endElement方法中的值(在將它解析爲數字之前修整空白),然後清除緩衝區。

下面是一個ContentHandler如何工作的例子。它跟蹤其在正在讀取的XML中的位置,並在元素文本到達元素末尾時保存元素文本,當文本與基於當前路徑的對象屬性相匹配時:

class DanceContentHandler extends DefaultHandler { 

    private List tagStack = new ArrayList(); 
    private StringBuilder buffer = new StringBuilder(); 
    private Dance dance = new Dance(); 

    public void startElement(String namespaceURI, String localName, 
    String qName, Attributes atts) throws SAXException { 
     buffer.clear(); 
     tagStack.add(localName); 
     if ("[dance]".equals(tagStack.toString()) { 
      // populate title and id of dance object from atts 
     } 
    } 

    public void endElement(String namespaceURI, String localName, 
    String qName) throws SAXException { 
     String text = buffer.toString().trim(); 
     switch (tagStack.toString()) { 
      case "[dance, type]": 
       dance.setType(text); 
       break; 
      case "[dance, scene]": 
       dance.setScene(text); 
       break; 
      case "[dance, numberOfDancers]": 
       dance.setNumberOfDancers(Integer.parseInt(text)); 
       break; 
      case "[dance, music]": 
       dance.setMusic(text); 
       break; 
      case "[dance, dancers, dancer]": 
       dance.getDancers().add(text); 
       break; 
      case "[dance, number]": 
       dance.setNumber(Integer.parseInt(text)); 
       break; 
     } 
     buffer.clear();  
     tagStack.remove(tagStack.size() - 1); 
    } 

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

    // return populated domain object 
    public Dance getDance() { 
     return dance; 
    } 

}