SAX Parser - NumberFormatException

时间:2016-05-31 12:15:00

标签: java xml sax saxparser

我尝试通过SAX Parser解析下一个xml文档:

<?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);

问题出在哪里?

2 个答案:

答案 0 :(得分:0)

在您的代码中,您尝试将子字符串new String(ch, start, length)解析为整数。 NumberFormatException只是说出它的内容 - 换行符不能解释为数字:

java.lang.NumberFormatException: For input string: "

"

如果你的xml中有这样的东西,可能会发生这种情况:

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

检查你的xml输入。

答案 1 :(得分:0)

变量thisElement中的元素文本与您认为xml中当前位置的任何内容都不同步。从错误消息中可以看出,它在一个预期存在数字的点上保存了一串带有换行符的空格,其中该空白流可能是当前元素之前的元素文本。

您的字符方法不符合SAX文档。每个元素可以由解析器多次调用characters方法,在调用endElement方法之前,您无法确定是否拥有完整的元素文本。见the Oracle tutorial

  

解析器不需要一次返回任何特定数量的字符。解析器可以一次从单个字符返回任何内容,但仍然是符合标准的实现。因此,如果您的应用程序需要处理它看到的字符,那么使用characters()方法在java.lang.StringBuffer中累积字符并且只有在您确定已找到所有字符时才对它们进行操作是明智的。 / p>

characters方法除了将内容保存在缓冲区(例如,附加到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; 
    }

}