1
??????????????
前言
本文闡述了
Apusic
對(duì)
XML
文件處理的詳細(xì)分析,及其現(xiàn)有情況下
Apusic
對(duì)
XML
文件解析存在的問題。
2
??????????????
Apusic
如何處理
XML
文件
Apusic
服務(wù)器對(duì)于
XML
文件解析應(yīng)該分為兩種情況:一種
Apusic
需要加載的
XML
文件。如
:Apusic
的配置文件,
J2EE
應(yīng)用的
web.xml,application.xml
文件等。另外一種是用戶代碼中使用
DocumentBuilderFactory
,
SAXParserFactory
來解析自己的
XML
文件。對(duì)于上面兩種情況的
XML
文件,
Apusic
是予以不同處理的。以下對(duì)此做具體說明。
2.1
????
解析
Apusic
的配置文件及其
J2EE
應(yīng)用的
web.xml,application.xml…etc
對(duì)于這一塊的解析,我們現(xiàn)在是采用自己的
XML
解析器來實(shí)現(xiàn)的,我們自己的
XML
解析器就是
com.apusic.xml.parsers
,
com.apusic.xml.reader
下的相關(guān)類來處理的,和朱華明討論過,我們對(duì)于上述文件采用自己的解析器處理是存在優(yōu)勢的。因?yàn)槲覀儗?duì)這些文件的結(jié)構(gòu)很了解。效率應(yīng)該會(huì)高于任何第三方的
XML
解析器。但是我們的解析器可能也會(huì)存在一些不足的地方,對(duì)于一些復(fù)雜的
XML
結(jié)構(gòu)的處理可能會(huì)存在問題。由于考慮到效率問題,所以這一塊應(yīng)該不需要使用第三方的
XML
解析器,還是使用我們自己的解析器為好。
2.2
????
用戶代碼中解析自己的
XML
文件
用戶應(yīng)用程序使用
DocumentBuilderFactory, SAXParserFactory
對(duì)自己的
XML
解析時(shí),由于我們?cè)?/span>
Apusic.jar
中,對(duì)
META-INF/service/
文件夾下設(shè)置了
javax.xml.parsers.DocumentBuilderFactory , javax.xml.parsers.SAXParserFactory
兩個(gè)屬性的值,并指向了
Xerces,
所以用戶在解析
XML
時(shí),缺省情況下使用的就是
Xerces API
進(jìn)行操作的。因此這一塊應(yīng)該是不會(huì)存在問題。
至于設(shè)置此屬性后是如何利用
Xerces API
進(jìn)行解析
XML
的原理,當(dāng)你閱讀了
Java
相關(guān)源代碼后就可以明白。具體可以閱讀
javax.xml.parsers
包下的
DocumentBuilderFactory.class,SAXParserFactory.class
類的
newInstance
方法。
3
??????????????
現(xiàn)存問題分析
現(xiàn)在我們會(huì)遇到修改
Apusic
配置文件后,
Apusic
無法啟動(dòng)的情況。這種情況主要是因?yàn)槲覀兪褂昧俗约旱?/span>
XML
解析器。而我們的解析器在處理
UTF-8
編碼文件時(shí)存在問題,因?yàn)槲谋疚募谖募念^部存在
BOM? (Byte Order Mark)
標(biāo)識(shí)
,
而這個(gè)
BOM
標(biāo)識(shí)是用來表示文件的字節(jié)順序。對(duì)于不同編碼格式的文件存在不同的
BOM
標(biāo)識(shí)
,
文件的
BOM
標(biāo)識(shí)規(guī)范可以參考下表(表
1
),由于
UTF-8
文件不存在字節(jié)順序的問題,所以這個(gè)文件
BOM
標(biāo)識(shí)在
UTF-8
編碼方式下是可有可無的。而當(dāng)我們修改配置文件并保存后,如果存在
BOM
標(biāo)識(shí),我們的解析器就會(huì)出錯(cuò),不存在
BOM
標(biāo)識(shí)時(shí),我們的解析器就能夠正確工作。所以我們需要在解析
UTF-8
的時(shí)候,判斷頭部是否包含
UTF-8
的
BOM
標(biāo)識(shí),如果有就需要跳過去。代碼修改主要是在
XmlReader.java
文件中做如下處理:
//skip UTF-8 BOM (byte order mark)
if (count >= 3 && pos == 0){
if (buffer[0] == (byte)0xEF &&
buffer[1] == (byte)0xBB &&
buffer[2] == (byte)0xBF){
pos += 3;
}
}
|
?
UTF-8
|
EF BB BF
|
UTF-16 Big Endian
|
FE FF
|
UTF-16 Little Endian
|
FF FE
|
UTF-32 Big Endian
|
00 00 FE FF
|
UTF-32 Little Endian
|
FF FE 00 00
|
?
(
表
1)
?
為什么我們對(duì)
UTF-16,UTF-32
等編碼方式文件存在
BOM
標(biāo)識(shí)時(shí)沒有問題呢?其實(shí)這個(gè)問題應(yīng)該是
Java
的一個(gè)
bug
,
Java
的文本流在處理其他編碼方式的時(shí)候能夠很好的處理這個(gè)
BOM
標(biāo)識(shí),但是對(duì)于
UTF-8
編碼時(shí)不能夠正確處理。該
bug
可以參考以下地址:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4508058
?