`
Thomas会Coding
  • 浏览: 96020 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

解析XML时遇见的编码问题,invalid token

阅读更多

由于sax是触发式的解析xml流, 在手持设备的系统中,应用相当广泛. 在Android的应用开发中,自然也偏向于选择sax来解析xml了. 

在做一份rss应用中,需要解析baidu.com的rss文件时遇到了not well-formed的错误. 查询了相关资料以及不断debug and log之后, 终于确定了是文件编码遇到了问题. 

在此说下我的一些理解, 如有错误请留言指出 

首先国内资讯内容提供商使用的rss编码各不相同 网易使用gb2312, 新浪utf-8, 百度GBK 等等. 

1. 当URL请求rss.xml后, 通过openStream将返回一个InputStream的字节流对象, 字节流本身是不带编码信息的. 

(ps. 为什么说字节流前3个字节,保存的是编码信息? 我通过测试byte[3]的数组,比对UTF8字节数组(-17,-69,-65) 无论是否是UTF8编码均不能匹配上) 

2. 得到字节流后,通常是可以直接使用InputStream对象去生成一个InputSource对象,来给saxParser或者是XmlReader进行解析的. 默认的情况下, parser解析的InputSource对象是按照utf8编码方式的, 所以,在不做任何处理时, utf8编码的xml文件解析是正常的. 

3. 当遇到Gbk,或者gb2312编码时,解析ANSI字符是没有问题的,解析到中文时,parser是按照默认的UTF8编码进行解析的, UTF8是每个字符分配3字节, gb2312是分配两字节,必然会造成错误.这时也就报出了not well-formed error. 

当时注意到inputSource有个setEncoding的方法,是告诉sarpar使用何种编码去解析这个inputStream, 你可以设置使用GBK去解析这个stream, 但是资源文件的编码都是utf8,而你使用GBK去解析明显是不符合的. 

4. SetEncoding是不会将编码进行转换的,仅仅是告诉sarpar如何去解析, 那么遇到xml encoding是gbk gb2312的情况下, 可以使用inputStreamReader的方式, 

inputStreamReader(inputStream, charsetName)来指定编码生成字符流.这里显然发生了编码转换. 

然后传递这个字符流对象到InputSource对象,这个对象在接受字符流时,是不能setEncoding的, 原因也很简单,字符流是带编码信息的,仍然不放心可以再次setEncoding,(不过是无效的) 

5. 这样最后只要通过判别文件的编码方式,然后告诉sarpar如何去解析,程序就可以正常执行了. 

识别字节流的编码方式可以google查询到很多方法,常用的是通过mozilla提供的一个开源工具来识别的. 目前最新为: cpdetector_1.0.8 可以在SourceForge下载到. 

关键代码: 

 

View Code JAVA1 

 

XMLContentHandler handler = new XMLContentHandler(); 

XMLReader reader = null; 

InputSource is = null; 

try{   

URL url = new URL(w163);  

SAXParserFactory parserFactory = SAXParserFactory.newInstance(); 

SAXParser saxParser = parserFactory.newSAXParser(); 

if(!isUTF8(url)){ 

InputStream stream = url.openStream(); 

InputStreamReader streamReader = new InputStreamReader(stream,"GBK"); 

is = new InputSource(streamReader); 

}else{ 

is = new InputSource(url.openStream()); 

is.setEncoding("UTF-8"); 

reader = saxParser.getXMLReader(); 

reader.setContentHandler(handler); 

}catch(Exception e){ 

Log.e(TAG, "Exception updateRss()"); 

try { 

reader.parse(is); 

} catch (IOException e) { 

e.printStackTrace(); 

} catch (SAXException e) { 

Log.e(TAG, e.getMessage()); 

        } 

 

 

其中isUTF8是通过mozilla的jar包来实现的,具体可以参考cpdetector使用方法的相关文章. 

分享到:
评论

相关推荐

    rlexception: invalid roslaunch xml syntax: no element found: lin

    在ROS(Robot Operating System)开发过程中,遇到`rlexception: invalid roslaunch xml syntax: no element found: line 1, column 0`这样的错误信息时,表明当前的`.launch`文件存在XML语法错误。具体来说,可能是...

    Invalid Token(解决方案).md

    Invalid Token(解决方案).md

    jsoup解析xml文件

    **jsoup解析XML文件** jsoup是一个非常流行的Java库,主要设计用于处理HTML文档,但它也支持解析XML。这个库提供了简洁的API,使得提取和操作网页数据变得异常简便。在给定的资源中,我们可以看到一个使用jsoup解析...

    OneNet一键token工具

    在使用OneNet一键token工具时,开发者需要了解以下几个关键知识点: 1. **OneNet平台**:这是中国移动提供的物联网开放平台,提供数据接入、存储、处理、分析及应用开发等服务。 2. **API接口**:OneNet平台提供了...

    c++ 解析 xml 源代码

    - 在处理XML时,要特别注意错误处理,如文件不存在、XML格式错误等。 - TinyXML库默认不进行XML验证,如果需要验证XML文档是否符合特定的DTD或XSD,需使用其他工具或库。 - 对于大型XML文件,考虑使用SAX解析器...

    org.xml.sax.SAXException: Invalid element

    NULL 博文链接:https://wilian.iteye.com/blog/1992365

    用dom4j解析xml时,用xpath的辅助包

    用dom4j解析xml时,经常需要用到xpath,由于dom4j-1.6.1.jar不包括jaxen-1.1-beta-6.jar,导致使用xpath报错。 其中jaxen-full.jar是为了解决ava.lang.NoClassDefFoundError: org/jaxen/JaxenException错误。 下载的...

    SVN版本冲突问题解决

    SVN冲突处理解决方法 1.SVN冲突产生的原因 2. 解决冲突的方式 3.注意事项 不同版本的同一个位置出现了不同的东西

    Invalid CSRF Token(解决方案).md

    Invalid CSRF Token(解决方案).md

    获取七牛token,失效重新获取

    前端javascript,获取七牛token,判断有没有失效,失效重新获取,未失效存到缓存下次使用。

    java-SAX解析XML、java正则表达式.

    Java编程语言在处理XML数据时提供了多种方法,其中SAX(Simple API for XML)解析器是一种基于事件驱动的解析方式,适用于处理大型XML文件。它不会一次性加载整个XML文档到内存,而是逐行读取,当遇到XML元素的开始...

    android layout XML解析错误的解决方法

    如果这一行存在格式问题,如额外的字符、缺失的引号或错误的编码,都可能导致解析错误。有时,即使XML语法没有其他明显错误,这行也可能导致问题。如果删除这行可以正常预览,可能是因为某些编辑器或工具不正确地...

    对XML进行parse时的InvalidUnicodecharacter(0x0)分析.pdf

    在解析XML时遇到"Invalid Unicode character (0x0)"错误,通常是由于XML文档中存在无效的Unicode字符,即Unicode码点0x0的字符。这个字符在Unicode标准中被认为是不可打印的控制字符,不应出现在XML文档的文本内容中...

    tinyxml2最新版本(来自github)

    在处理XML时,应该使用try-catch语句捕获可能的异常,以便正确处理错误。 ```cpp try { doc.LoadFile("invalid.xml"); } catch (tinyxml2::XMLException& e) { std::cerr () ; } ``` 5. **扩展与社区支持** ...

    Invalid or expired token(解决方案).md

    Invalid or expired token(解决方案).md

    多个delphi读写处理xml的示例文件..rar

    Delphi还支持基于事件的XML解析,通过实现IXMLReader和IXMLWriter接口,可以在解析或生成XML时触发自定义处理函数。这在处理大型XML文件或需要实时更新UI时特别有用。 5. **XML Schema验证** Delphi提供了对XML ...

Global site tag (gtag.js) - Google Analytics