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

[Android]分析 Sax解析Rss xml文件时,遇到的not well-formed错误

阅读更多
由于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使用方法的相关文章.



原文地址 http://www.lshine.com/index.php/2010/08/sax_not_well-formed/ 
分享到:
评论
2 楼 zhangjiajun1988 2011-04-02  
楼主,请教一下如何来判断编码,,还有就是如何URL转换为FILE ...
1 楼 lovext 2010-11-25  
不同网站提供的RSS,还有可能会有其他的不同,比如sina的description是CDATA,用sax的话就有可能只显示一行

相关推荐

    SAX解析XML文件实例

    一个项目同时用dom解析和sax解析xml文件貌似会报错,项目框架建一直是用sax和dom4j解析xml文件的。当我用dom解析xml文件。导入包后就报错识别不了xml文件的编码格式。于是做了一个sax解析xml文件的实例

    SAX解析超大XML文件 示例代码

    在处理大型XML文件时,传统的DOM(Document Object Model)解析方式可能会遇到性能问题,因为DOM会将整个XML文档加载到内存中,对于超大文件,这可能导致内存溢出。为了解决这个问题,我们可以采用流式解析的方式,...

    [Android]使用SAX解析XML文件

    SAX解析器在读取XML文件时,会触发一系列的事件,例如开始文档、结束文档、开始元素、结束元素等。开发者需要创建一个实现了SAX解析器接口的类,即`DefaultHandler`或自定义的处理器,然后重写这些事件的方法,以便...

    android使用SAX解析xml

    本篇文章将详细介绍如何在Android环境中使用SAX解析器来处理从网络获取的XML文件。 1. **XML与SAX解析基础** - XML是一种结构化的文本数据表示方式,它定义了标签、属性等规则,使数据具有自解释性。 - SAX解析器...

    Sax解析XML文件解析

    3. **错误处理**:SAX解析器会在遇到错误时抛出异常,需要妥善处理这些异常。 在实际应用中,开发者可以根据需求选择合适的XML解析方式。对于小规模、结构简单且需要随机访问的XML,DOM解析可能是更好的选择;而...

    Sax解析xml文件

    在Android和Java编程中,处理XML文件是常见的任务,而SAX(Simple API for XML)是一种轻量级、事件驱动的XML解析器,它以流式方式读取XML文档,只在需要时解析内容,因此非常适合处理大体积的XML文件。 SAX解析器...

    android 使用Sax解析XML 源码实例

    使用SAX方式解析XML SAX 是读取和操作 XML 数据的更快速、更轻量的方 法。SAX 允许您在读取文档时处理它,从而不必等待整个文档被存储之后才采取操作。它不涉及 DOM 所必需的开销和概念跳跃。 SAX API是一个基于事件...

    android下解析xml文件的demo

    SAX解析器是事件驱动的,它逐行读取XML文件,遇到每个元素时触发相应的事件。这种方式适用于处理大型XML文件,因为它不需要一次性加载整个文件。 在"ReadXMLDemo"中,使用SAX解析的步骤如下: - 实现`...

    sax解析xml文件

    当解析器读取XML文件时,它会触发一系列的事件,如开始文档、结束文档、开始元素、结束元素等。开发者通过实现SAX解析器的回调接口,为这些事件编写处理方法。例如: 1. `startDocument()`:在解析开始时调用。 2. ...

    android SAX PULL 解析XML文件 代码 详解

    首先,SAX解析是一种基于事件驱动的解析方式,它不需要一次性加载整个XML文档到内存中,而是逐行读取,当遇到特定的XML元素(如开始标签、结束标签、属性等)时,会触发相应的事件处理器。这种方式对内存消耗较小,...

    android使用sax解析本地xml

    1. 当处理XML文件时,确保文件路径正确,且应用有读取文件的权限。 2. 考虑异常处理,因为解析过程中可能出现各种异常,如文件不存在、格式错误等。 3. 在事件处理器的回调方法中,不要执行耗时操作,否则可能阻塞...

    android SAX解析String类型 XML 字符串

    在Android开发中,处理XML数据是一项常见的任务,无论是从网络获取还是本地存储。"SAX解析String类型XML字符串"就是一种高效且...在处理StringXml压缩包文件时,可以按照这个思路进行操作,实现XML数据的解析和显示。

    android 以SAX方式解析xml

    SAX解析器读取XML文件时,遇到每个元素、属性、文本等都会触发相应的事件,开发者需要通过实现ContentHandler接口来处理这些事件。这种方式节省了内存,但需要编写更多的代码来处理解析过程。 **步骤1:引入SAX解析...

    Android之SAX解析XML

    本文将深入探讨如何在Android环境中使用SAX(Simple API for XML)解析XML文件。SAX是一种事件驱动的解析器,它在读取XML文档时触发一系列事件,开发者可以注册事件处理器来处理这些事件,从而实现对XML数据的高效、...

    读取RSS-SAX解析XML实例(java版)

    标题"读取RSS-SAX解析XML实例(java版)"所涉及的知识点主要集中在两个方面:一是如何读取RSS(Really Simple Syndication)数据,二是使用SAX解析XML文件。 RSS是一种用于发布新闻、博客和其他定期更新内容的格式...

    'Android sax引擎解析xml文件

    SAX(Simple API for XML)是一种事件驱动的XML解析器,它以流式的方式处理XML文档,不需要一次性加载整个文件到内存,因此在处理大体积XML文件时具有内存效率高的优势。本篇将深入探讨如何使用Android中的SAX引擎...

    SAX--XML文件读写

    在Android开发中,由于内存限制和性能优化的需求,通常会选择SAX(Simple API for XML)解析器来读取XML文件,而非DOM(Document Object Model)解析器,因为SAX是基于事件驱动的,它按需逐个处理XML元素,占用内存...

    Android SAX、DOM、Pull解析xml文件案例讲解

    XML(eXtensible Markup Language)是一种用于存储和传输数据的标准格式,特别是在移动应用开发,如Android中,解析XML文件是常见的任务。本篇将详细讲解Android中三种主要的XML解析方式:SAX(Simple API for XML)...

    android sax解析xml文件

    SAX解析器在读取XML文件时会触发一系列的事件,例如开始文档、开始元素、字符数据、结束元素等。开发者通过实现SAX解析器的回调接口,定义这些事件的处理器方法,从而在解析过程中进行相应的操作。 **Android中的...

    android xml文件解析 SAX

    SAX是一种事件驱动的XML解析器,它不会像DOM解析器那样将整个XML文档加载到内存中,而是逐行读取,遇到每个元素或属性时触发相应的事件回调。这种方式节省了内存,特别适合处理大型XML文件。 1. **SAX解析的基本...

Global site tag (gtag.js) - Google Analytics