您好,欢迎访问三七文档
当前位置:首页 > 办公文档 > 工作范文 > 对XML进行parse时的InvalidUnicodecharacter(0x0)分析
对XML进行parse时的InvalidUnicodecharacter(0x0)分析XML在搜索引擎的低端起到了非常重要的作用,可是由于相当多数的网络上的Rssfeed或者XMLfeed都是直接从数据库文件生成的,因此极有可能包含有一些非常字符,而这些字符在XML进行Parse的时候就会带来InvalidUnicodecharacter(0x0)这样的错误或者是org.xml.sax.SAXParseException:AninvalidXMLcharacter(Unicode:0x0)wasfound,如何解决这样的错误?先看看Unicode的一些基础知识:Unicode最初设计是作为一种固定宽度的16位字符编码。在Java编程语言中,基本数据类型char初衷是通过提供一种简单的、能够包含任何字符的数据类型来充分利用这种设计的优点。不过,现在看来,16位编码的所有65,536个字符并不能完全表示全世界所有正在使用或曾经使用的字符。于是,Unicode标准已扩展到包含多达1,112,064个字符。那些超出原来的16位限制的字符被称作增补字符。Unicode标准2.0版是第一个包含启用增补字符设计的版本,但是,直到3.1版才收入第一批增补字符集。由于J2SE的5.0版必须支持Unicode标准4.0版,因此它必须支持增补字符。对增补字符的支持也可能会成为东亚市场的一个普遍商业要求。政府应用程序会需要这些增补字符,以正确表示一些包含罕见中文字符的姓名。出版应用程序可能会需要这些增补字符,以表示所有的古代字符和变体字符。中国政府要求支持GB18030(一种对整个Unicode字符集进行编码的字符编码标准),因此,如果是Unicode3.1版或更新版本,则将包括增补字符。台湾标准CNS-11643包含的许多字符在Unicode3.1中列为增补字符。香港政府定义了一种针对粤语的字符集,其中的一些字符是Unicode中的增补字符。最后,日本的一些供应商正计划利用增补字符空间中大量的专用空间收入50,000多个日文汉字字符变体,以便从其专有系统迁移至基于Java平台的解决方案。因此,Java平台不仅需要支持增补字符,而且必须使应用程序能够方便地做到这一点。由于增补字符打破了Java编程语言的基础设计构想,而且可能要求对编程模型进行根本性的修改,因此,JavaCommunityProcess召集了一个专家组,以期找到一个适当的解决方案。该小组被称为JSR-204专家组,使用Unicode增补字符支持的Java技术规范请求的编号。从技术上来说,该专家组的决定仅适用于J2SE平台,但是由于Java2平台企业版(J2EE)处于J2SE平台的最上层,因此它可以直接受益,我们期望Java2平台袖珍版(J2ME)的配置也采用相同的设计方法。不过,在了解JSR-204专家组确定的解决方案之前,我们需要先理解一些术语。代码点、字符编码方案、UTF-16:这些是指什么?不幸的是,引入增补字符使字符模型变得更加复杂了。在过去,我们可以简单地说“字符”,在一个基于Unicode的环境(例如Java平台)中,假定字符有16位,而现在我们需要更多的术语。我们会尽量介绍得相对简单一些—如需了解所有详细的讨论信息,您可以阅读Unicode标准第2章或Unicode技术报告17“字符编码模型”。Unicode专业人士可略过所有介绍直接参阅本部分中的最后定义。字符是抽象的最小文本单位。它没有固定的形状(可能是一个字形),而且没有值。“A”是一个字符,“€”(德国、法国和许多其他欧洲国家通用货币的标志)也是一个字符。字符集是字符的集合。例如,汉字字符是中国人最先发明的字符,在中文、日文、韩文和越南文的书写中使用。编码字符集是一个字符集,它为每一个字符分配一个唯一数字。Unicode标准的核心是一个编码字符集,字母“A”的编码为004116和字符“€”的编码为20AC16。Unicode标准始终使用十六进制数字,而且在书写时在前面加上前缀“U+”,所以“A”的编码书写为“U+0041”。代码点是指可用于编码字符集的数字。编码字符集定义一个有效的代码点范围,但是并不一定将字符分配给所有这些代码点。有效的Unicode代码点范围是U+0000至U+10FFFF。Unicode4.0将字符分配给一百多万个代码点中的96,382代码点。增补字符是代码点在U+10000至U+10FFFF范围之间的字符,也就是那些使用原始的Unicode的16位设计无法表示的字符。从U+0000至U+FFFF之间的字符集有时候被称为基本多语言面(BMP)。因此,每一个Unicode字符要么属于BMP,要么属于增补字符。字符编码方案是从一个或多个编码字符集到一个或多个固定宽度代码单元序列的映射。最常用的代码单元是字节,但是16位或32位整数也可用于内部处理。UTF-32、UTF-16和UTF-8是Unicode标准的编码字符集的字符编码方案。UTF-32即将每一个Unicode代码点表示为相同值的32位整数。很明显,它是内部处理最方便的表达方式,但是,如果作为一般字符串表达方式,则要消耗更多的内存。UTF-16使用一个或两个未分配的16位代码单元的序列对Unicode代码点进行编码。值U+0000至U+FFFF编码为一个相同值的16位单元。增补字符编码为两个代码单元,第一个单元来自于高代理范围(U+D800至U+DBFF),第二个单元来自于低代理范围(U+DC00至U+DFFF)。这在概念上可能看起来类似于多字节编码,但是其中有一个重要区别:值U+D800至U+DFFF保留用于UTF-16;没有这些值分配字符作为代码点。这意味着,对于一个字符串中的每个单独的代码单元,软件可以识别是否该代码单元表示某个单单元字符,或者是否该代码单元是某个双单元字符的第一个或第二单元。这相当于某些传统的多字节字符编码来说是一个显著的改进,在传统的多字节字符编码中,字节值0x41既可能表示字母“A”,也可能是一个双字节字符的第二个字节。UTF-8使用一至四个字节的序列对编码Unicode代码点进行编码。U+0000至U+007F使用一个字节编码,U+0080至U+07FF使用两个字节,U+0800至U+FFFF使用三个字节,而U+10000至U+10FFFF使用四个字节。UTF-8设计原理为:字节值0x00至0x7F始终表示代码点U+0000至U+007F(BasicLatin字符子集,它对应ASCII字符集)。这些字节值永远不会表示其他代码点,这一特性使UTF-8可以很方便地在软件中将特殊的含义赋予某些ASCII字符。经修订的UTF-8Java平台对经修订的UTF-8已经很熟悉,但是,问题是应用程序开发人员在可能包含增补字符的文本和UTF-8之间进行转换时需要更加留神。需要特别注意的是,某些J2SE接口使用的编码与UTF-8相似但与其并不兼容。以前,此编码有时被称为“JavamodifiedUTF-8”(经Java修订的UTF-8)或(错误地)直接称为“UTF-8”。对于J2SE5.0,其说明文档正在更新,此编码将统称为“modifiedUTF-8”(经修订的UTF-8)。经修订的UTF-8和标准UTF-8之间之所以不兼容,其原因有两点。其一,经修订的UTF-8将字符U+0000表示为双字节序列0xC00x80,而标准UTF-8使用单字节值0x0。其二,经修订的UTF-8通过对其UTF-16表示法的两个代理代码单元单独进行编码表示增补字符。每个代理代码单元由三个字节来表示,共有六个字节。而标准UTF-8使用单个四字节序列表示整个字符。Java虚拟机及其附带的接口(如Java本机接口、多种工具接口或Java类文件)在java.io.DataInput和DataOutput接口和类中使用经修订的UTF-8实现或使用这些接口和类,并进行序列化。Java本机接口提供与经修订的UTF-8之间进行转换的例程。而标准UTF-8由String类、java.io.InputStreamReader和OutputStreamWriter类、java.nio.charset设施(facility)以及许多其上层的API提供支持。由于经修订的UTF-8与标准的UTF-8不兼容,因此切勿同时使用这两种版本的编码。经修订的UTF-8只能与上述的Java接口配合使用。在任何其他情况下,尤其对于可能来自非基于Java平台的软件的或可能通过其编译的数据流,必须使用标准的UTF-8。需要使用标准的UTF-8时,则不能使用Java本机接口例程与经修订的UTF-8进行转换。因此通常来说,0x00-0x20都会引起一定的问题,又因为这些字符不可见,因此用通常的编辑器进行编辑的时候找不到问题所在。解决方案:catyourfile|od-x可以看到如果有0000这样的字符就是问题所在了。MSDN给出的片段代码有帮助:internalvoidCheckUnicodeString(Stringvalue){for(inti=0;ivalue.Length;++i){if(value[i]0xFFFD){thrownewException(InvalidUnicode);}elseif(value[i]0x20&&value[i]!='t'&value[i]!='n'&value[i]!='r'){thrownewException(InvalidXmlCharacters);}}而为了简单起见,我干脆用Perl将里面的字符替换调发现也是一个很好的办法。前提是必须用正确的编码读取处理的xml。
本文标题:对XML进行parse时的InvalidUnicodecharacter(0x0)分析
链接地址:https://www.777doc.com/doc-2465479 .html