【问题标题】:SAX Parser - NumberFormatExceptionSAX 解析器 - NumberFormatException
【发布时间】:2016-05-31 12:14:59
【问题描述】:

我尝试通过 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);

问题可能出在哪里?

【问题讨论】:

    标签: java xml sax saxparser


    【解决方案1】:

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

    java.lang.NumberFormatException: For input string: "
    
    "
    

    如果您的 xml 中有类似的内容,则可能会发生这种情况:

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

    检查您的 xml 输入。

    【讨论】:

    • 感谢您的回答,但我在标签之间没有换行符。我的 xml 文件和我的帖子一模一样。
    【解决方案2】:

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

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

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

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

    }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-14
      • 2015-04-12
      • 2012-08-27
      • 1970-01-01
      • 1970-01-01
      • 2014-03-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多