今天在做android程序,从网上读取xml文档,对其进行控制,可是在读到中文的时候就会出现错误:org.apache.harmony.xml.ExpatParser$ParseException:At line 4,column 11:not well-formed.觉得很奇怪,有些网站RSS的xml能够读取,有些不能读取.然后我对比几个Rss的xml文档,最后发现,原来是xml的编码出现了错误.<?xml version="1.0" encoding="utf-8" ?> ,<?xml version="1.0" encoding="gbk" ?> 手机支持的编码有utf-8,gb2312,还有IO-8什么的,(忘了),而gbk编码手机不支持,所以我们需要将xml的编码转换成手机能够识别的编码.
解决办法:一般从网上读取xml是用xml的单一输入源InputSource进行存储xml内容.例如:
//下面的网址的xml是gbk编码格式
URL url=new URL(http://www.gdin.net/rss.php);
InputSource ins=new InputSource(url.openStream());
如果此时你直接使用xmlReader.parse(ins);的话就会出现上面的错误.接下来,我们使用一个方法,将gbk改成UTF-8格式,也就是将xml开头的一句话,<?xml version="1.0" encoding="gbk" ?> 改成手机能够识别的,<?xml version="1.0" encoding="utf-8" ?>就行了.
ins=TransformEncoder(ins,"gbk","UTF-8");
private InputSource TransformEncoder(InputSource is,String oldCharet,String newCharet)
{
// TODO Auto-generated method stub
//建立要返回的xml单一输入源
InputSource newis=new InputSource();
//输入流
InputStream in=is.getByteStream();
//Log.v("inputstram=",in.toString());
//数组,存储输入流信息
byte[] by=new byte[5096];
//存储xml内容
String theString="";
try {
int length=in.read(by,0,by.length);
while(length>0)
{
String temp=EncodingUtils.getString(by,0,length,"gb2312");
theString=theString+temp;
length=in.read(by,0,by.length);
}
//对xml文件中的编码进行转换
theString=theString.replaceFirst(oldCharet, newCharet);
//删除文件末的无效字符,在这里用不到
theString=theString.substring(0, theString.lastIndexOf(">")+1);
//下面的步骤将xml内容重新转换成InputSource
//输出缓存区
ByteArrayOutputStream out = new ByteArrayOutputStream();
by=new byte[5096];
//将xml内容转换成字节数组
by=theString.getBytes("UTF-8");
//写进输出缓存
out.write(by);
//将输出缓存转换成输入缓存
ByteArrayInputStream bin=new ByteArrayInputStream(out.toByteArray());
//将输入缓存转换成输入流
in=(InputStream)bin;
//将输入流转换成xml单一输入源
newis=new InputSource(in);
return newis;
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException ex) {
// TODO Auto-generated catch block
ex.printStackTrace();
}
return null;
}
那么经过这个步骤就能够识别xml的,遇到其他编码,也可以根据这个方法进行转换,变成自己所需要的编码.
在此还得说明一下,在TransformEncoder(InputSource is,String oldCharet,String newCharet)方法中,在流转换中的过程是这样的:
InputSource流-->InputStream流-->byte[]-->String-->对String进行修改-->byte[]-->ByteArrayOutStream缓冲流-->ByteArrayInputStream缓冲流-->InputStream流-->InputSource流
使对于新手来说,这个过程累死人呀.InputStream转换成byte[],大部新手都会,但是byte[]转换成InputStream流却比较困难,因为没有直接的方法进行转化,需要借助ByteArrayOutStream缓冲流的帮忙.