最近一个处理非常大的XML的程序遭遇了如下的异常:
org.xml.sax.SAXParseException:Parser has reached the entity expansion limit "64,000" set by the Application.
查了查,原来是在单个xml文件中实体引用超过了默认值64000个。你用dom和sax解析XML都可能会遇到这个问题,这印证了我的猜测,java的dom是用sax来实现的。
解决方法很简单,运行Java的时候,加上参数-DentityExpansionLimit=xxxxx,你也可以在代码中解析XML前,用代码设置这个参数System.setProperty("entityExpansionLimit", "xxxxx");。xxxxx代表设定的单文件实体引用数最大值。
--------
那么这个xxxxx该怎么选择呢?
其实也很简单,选择你认为可能出现的最大值就好了,比你的文件里面的实体数多,自然就没问题了。
--------
那么如果你想知道某个文件里面有多少个实体引用该怎么办呢(放心我肯定不建议你去数)?
对,也很简单,首先我们知道实体引用都是“&"开头“;”结尾,所以我们可以用如下命令来计算:
grep -c "&.*;" yourfile.xml
其实,&在xml里表示为&的形式,所以,一个合法的xml内,有多少&就有多少实体引用,so,上面的命令效率更高的版本是:
grep -c "&" yourfile.xml
--------
为什么会对最大的实体引用数做出限制呢?这点我有些疑惑,难道要为解析实体引用准备缓存空间?但是做出来自动增长的缓存也不是不可能的啊。DentityExpansionLimit参数的问题是,如果要处理无法预期大小的xml文件怎么办?你设置为100万,xml文件里面有200万个实体引用,你有办法么?
technorati tags: DentityExpansionLimit, dom, Javascript, java异常, sax, SAXParseException, xml


请不要吝惜您的评论,每一条评论,都是我在漫漫长夜前行的力量
4 条评论:
我用JDOM没有遇到过类似问题啊?
10:04 上午
这个问题是由过多的实体引用造成的,只是文件大到不会引发。你可以构造一个有大量实体引用的XML测试你的老程序。
另外,我怀疑这个问题也跟Java版本有关系,我目前用的还是1.4x
9:37 下午
我对流程不太熟悉,所以不知道如何去设置参数,能说的更明白点吗?
12:23 下午
运行的时候加上参数就是说,命令行运行java的时候,把参数写在命令行里,java -classpath=xxxxx -DentityExpansionLimit=xxxxx yourclassname 。
或者在你程序的代码里面靠前的位置加上这句System.setProperty("entityExpansionLimit", "xxxxx");。
12:35 下午
发表评论
<< 主页