【问题标题】:SAXParser got ArrayIndexOutOfBoundsException while parser a CDATA more than 1033 charactersSAXParser 在解析超过 1033 个字符的 CDATA 时得到 ArrayIndexOutOfBoundsException
【发布时间】:2015-11-27 10:10:59
【问题描述】:

我想使用 XML 作为一个小型数据库来存储文章。 当我使用 SAXParser 来解析这个 XML 时,我得到了一个 ArrayIndexOutOfBoundsException

我为此做了一个小例子。 XML 文件:

<?xml version="1.0" encoding="UTF-8"?>
<a>
    <b>
        <c>
            <![CDATA[
1111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111
]]>
        </c>
    </b>
</a>

我得到的异常:

java.lang.ArrayIndexOutOfBoundsException
    at java.lang.System.arraycopy(Native Method)
    at org.gjt.xpp.impl.tokenizer.Tokenizer.next(Tokenizer.java:1274)
    at org.gjt.xpp.impl.pullparser.PullParser.next(PullParser.java:392)
    at org.gjt.xpp.sax2.Driver.parseSubTree(Driver.java:415)
    at org.gjt.xpp.sax2.Driver.parse(Driver.java:310)
    at javax.xml.parsers.SAXParser.parse(SAXParser.java:392)
    at javax.xml.parsers.SAXParser.parse(SAXParser.java:328)
    at com.sumy.xmlwikimanager.dao.XMLUtil.parserXML(XMLUtil.java:28)
    at com.sumy.xmlwikimanager.dao.XMLUtil.main(XMLUtil.java:68)
    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:497)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

解析器处理程序:

package com.sumy.xmlwikimanager.dao;

import com.sumy.xmlwikimanager.bean.WikiItem;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

/**
 * Created by Sumy on 2015/11/27 0027.
 */
public class DatabaseParserHandler extends DefaultHandler {

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        System.out.println("startElement: uri[" + uri + "] localName[" + localName + "] qName[" + qName + "]"); 
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        super.characters(ch, start, length);
        System.out.println(length);
    }
}

XMLUtil.java 只是有一个测试方法:

package com.sumy.xmlwikimanager.dao;

import org.xml.sax.SAXException;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.File;
import java.io.IOException;
/**
 * Created by Sumy on 2015/11/27 0027.
 */
public class XMLUtil {
    public static void parserXML(File file) {
        try {

            SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser parser = factory.newSAXParser();
            parser.parse(file, new DatabaseParserHandler());
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public static void main(String[] args) {

        parserXML(new File("Category.xml"));

    }
}

我测试:
如果 CDATA 内容的长度小于1034,程序可以正常工作。当我添加一些字符时,ArrayIndexOutOfBoundsException 会抛出。

我的程序有什么问题吗?

【问题讨论】:

  • 你能展示你的 parseXML 方法/XMLUtil 类吗?
  • @eis 我已经编辑了帖子,并添加了 XMLUtil 类。

标签: java xml


【解决方案1】:

您的实施没有问题。由于文档格式正确,因此不会导致错误。

这似乎是解析器实现的一个错误。已经有一个 bug report 用于显示相同堆栈跟踪的解析器。

【讨论】:

  • 使用中的解析器实现似乎是“XPP XML Pull Parser”。其他人则求助于using different implementation
  • XML 解析器还有其他jar 库 吗?我用过Dom4j,但是也有这个问题。
  • 感谢@eis。我使用 org.w3c.dom 解析 XML 并使用 DomReaderorg.w3c.dom.Document 转换为 Dom4j文档,避免使用SAXReader。它几乎可以正常工作。
  • 感谢@wero。对于这个问题找不到好的解决方案,只是避免在代码中使用“XPP XML Pull Parser”。
  • @sumy 您已经在使用javax.xml.parsers.SAXParser 接口,而不是一个好的特定实现。 JDK 通常提供与 XPP Pull Parser 不同的实现。所以你必须学习如何摆脱XPP。也许就像从您的项目中删除 pull-parser-xx.jar 一样简单。请研究此stackoverflow.com/a/1804281/3215527 以了解如何选择实现。如果没有其他帮助,请发布一个新问题。
猜你喜欢
  • 2012-07-30
  • 2011-11-16
  • 2011-06-18
  • 1970-01-01
  • 1970-01-01
  • 2012-12-18
  • 2010-12-02
  • 2012-05-24
  • 1970-01-01
相关资源
最近更新 更多