最近一個處理非常大的XML的程序遭遇了如下的異常:
org.xml.sax.SAXParseException:Parser has reached the entity expansion limit '64,000' set by the Application. (org.xml.sax.SAXParseException: 分析器已達到由應(yīng)用程序設(shè)置的實體擴展限制“64,000”。)
查了查,原來是在單個xml文件中實體引用超過了默認(rèn)值64000個。你用dom和sax解析XML都可能會遇到這個問題,這印證了我的猜測,java的dom是用sax來實現(xiàn)的。
解決方法很簡單,運行Java的時候,加上參數(shù)-DentityExpansionLimit=xxxxx,你也可以在代碼中解析XML前,用代碼設(shè)置這個參數(shù)System.setProperty('entityExpansionLimit', 'xxxxx');。xxxxx代表設(shè)定的單文件實體引用數(shù)最大值。
--------
那么這個xxxxx該怎么選擇呢?
其實也很簡單,選擇你認(rèn)為可能出現(xiàn)的最大值就好了,比你的文件里面的實體數(shù)多,自然就沒問題了。
--------
那么如果你想知道某個文件里面有多少個實體引用該怎么辦呢(放心我肯定不建議你去數(shù))?
對,也很簡單,首先我們知道實體引用都是“&'開頭“;”結(jié)尾,所以我們可以用如下命令來計算:
grep -c '&.*;' yourfile.xml
其實,&在xml里表示為&的形式,所以,一個合法的xml內(nèi),有多少&就有多少實體引用,so,上面的命令效率更高的版本是:
grep -c '&' yourfile.xml
--------
為什么會對最大的實體引用數(shù)做出限制呢?這點我有些疑惑,難道要為解析實體引用準(zhǔn)備緩存空間?但是做出來自動增長的緩存也不是不可能的啊。DentityExpansionLimit參數(shù)的問題是,如果要處理無法預(yù)期大小的xml文件怎么辦?你設(shè)置為100萬,xml文件里面有200萬個實體引用,你有辦法么?
|