Java XML SAX 解析注意
什么时候可以把解析值赋给对象
一般从网上看到的sax解析,都是在Handler中的characters方法进行对象数据的赋值。
示例代码如下:
private TransportFile parseXML(String xml) {
SAXParserFactory saxfac = SAXParserFactory.newInstance();
try {
SAXParser saxparser = saxfac.newSAXParser();
InputStream is = new ByteArrayInputStream(xml.getBytes());
MySAXHandler handler = new MySAXHandler();
saxparser.parse(is, handler);
return handler.getData();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private class MySAXHandler extends DefaultHandler{
String currentTagName = "";
TransportFile mData = null ;
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
currentTagName = qName ;
if("file".equals(qName)){
mData = new TransportFile();
}
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
String str = new String(ch,start,length);
if("guid".equals(currentTagName)){
mData.guid = str;
}else if("name".equals(currentTagName)){
mData.name = str;
}else if("type".equals(currentTagName)){
mData.type = str;
}else if("length".equals(currentTagName)){
mData.length = Long.parseLong(str);
}else if("index".equals(currentTagName)){
mData.index = Integer.parseInt(str);
}else if("count".equals(currentTagName)){
mData.count = Integer.parseInt(str);
}else if("data".equals(currentTagName)){
mData.data = Base64.decode(str);
}
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
currentTagName = "";
}
public TransportFile getData(){
return mData ;
}
}
普通的使用场景中上述代码没有问题,但是当xml中某一标签的内容很长时,就会引发上述代码的bug。
实践发现sax解析每次也就解析1k左右的数据,超出部分其实是要分段多次解析的。
所以问题来了,如果在characters方法中解析,那么其他几段的数据仍然会不断覆盖最终返回对象中的数据,导致数据丢失。
因此,对于赋值给最终传回对象的数据,在characters阶段只能不断拼接,解析必须在endElement时才可以完成。否则当数据内容比较大的时候,网上代码中的bug就会凸显出来。
顺便贴上我的代码:
private class MySAXHandler extends DefaultHandler{
String currentTagName = "";
TransportFile mData = null ;
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
currentTagName = qName ;
mStringBuilder = new StringBuilder();
if("file".equals(qName)){
mData = new TransportFile();
}
}
private StringBuilder mStringBuilder;
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
mStringBuilder.append(ch, start, length);
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
String str = mStringBuilder.toString();
if("guid".equals(currentTagName)){
mData.guid = str;
}else if("name".equals(currentTagName)){
mData.name = str;
}else if("type".equals(currentTagName)){
mData.type = str;
}else if("length".equals(currentTagName)){
mData.length = Long.parseLong(str);
}else if("index".equals(currentTagName)){
mData.index = Integer.parseInt(str);
}else if("count".equals(currentTagName)){
mData.count = Integer.parseInt(str);
}else if("data".equals(currentTagName)){
mData.data = Base64.decode(str);
}
currentTagName = "";
}
public TransportFile getData(){
return mData ;
}
}
characters方法参数注意
ch是当前解析到的字符数组,并不是精确的标签内的内容。
下面是解析第一个标签时characters中 ch 、 start、length输出:
===========characters ch: <?xml version='1.0' encoding='utf-8' standalone='yes' ?><file><guid>678c6f92-d617-40af-bb87-a80c3b2be91f</guid><name>0CAQLTZGO.jpg</name><type>image</type><length>71374</length><index>0</index><count>1</count><data>/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoK.....
===========characters start:31
===========characters length:36
真正当前需要的数据是ch数组从start开始的length个字符。
Java XML SAX 解析注意的更多相关文章
- Java用SAX解析XML
要解析的XML文件:myClass.xml <?xml version="1.0" encoding="utf-8"?> <class> ...
- Java XML Dom解析工具
Java XML Dom解析工具 缩进等 transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); ...
- JAVA使用SAX解析XML文件
在我的另一篇文章(http://www.cnblogs.com/anivia/p/5849712.html)中,通过一个例子介绍了使用DOM来解析XML文件,那么本篇文章通过相同的XML文件介绍如何使 ...
- java使用sax解析xml
目的:解析xml文件,并存入mysql,并且要解析的字段能一一对应.这里解析的是微博的文件,想要利用里面的article和person_id字段. 思路: 为了能得到person_id和article ...
- Java中Sax解析XML
SAX基于事件的解析,解析器在一次读取XML文件中根据读取的数据产生相应的事件,由应用程序实现相应的事件处理逻辑,即它是一种“推”的解析方式:这种解析方法速度快.占用内存少,但是它需要应用程序自己处理 ...
- 简单的java使用SAX解析xml
1.新建一个SAXTest类,继承import org.xml.sax.helpers.DefaultHandler类 package com.qiao.SrpingSource; import or ...
- XML SAX解析
SAX是一种占用内存少且解析速度快的解析器,它采用的是事件驱动,它不需要解析完整个文档,而是按照内容顺序,看文档某个部分是否符合xml语法,如果符合就触发相应的事件.所谓的事件就是些回调方法( cal ...
- JavaEE XML SAX解析
SAX解析XML @author ixenos SAX解析工具 SAX解析工具- Sun公司提供的.内置在jdk中.org.xml.sax.* 核心的API: SAXParser类: 用于读取和解析 ...
- 浅谈 Java Xml 底层解析方式
XML 使用DTD(document type definition)文档类型来标记数据和定义数据,格式统一且跨平台和语言,已成为业界公认的标准. 目前 XML 描述数据龙头老大的地位渐渐受到 Jso ...
随机推荐
- mahout学习
参考:http://www.360doc.com/content/14/0117/09/1200324_345883534.shtml Precondition: 启动Hadoop集群 bin/hdf ...
- 部署nexus服务
一.安装和启动 官网下载nexus-2.12安装包,地址:https://sonatype-download.global.ssl.fastly.net/nexus/oss/nexus-2.12.0- ...
- Android输入控件EditText和软键盘监听
1. 跳转到新的页面自动软键盘显示情况: 在配置清单文件AndroidManifest.xml文件,对Activity的windowSoftInputMode属性进行设置. stateUnspecif ...
- database lock
USE masterEXEC sp_lock select * from sys.sysprocesses where blocked<>0 DBCC INPUTBUFFER(120) k ...
- Python -- 网络编程 -- 抓取网页图片 -- 豆瓣妹子
首先分析页面URL,形如http://dbmeizi.com/category/[1-14]?p=[0-476] 图片种类对应编号: 1:'性感', 2:'有沟', 3:'美腿', 4:'小露点', ...
- markdown编辑器(颜色、大小、字体)
<font face="黑体">我是黑体字</font> <font face="微软雅黑">我是微软雅黑</font ...
- go语言的unsafe包(转)
The unsafe Package in Golang Golang的unsafe包是一个很特殊的包. 为什么这样说呢? 本文将详细解释. 来自go语言官方文档的警告 unsafe包的文档是这么说的 ...
- I/O模式总结
进程读取数据时要经过两个阶段: 1.等待内核准备数据: 2.将内核缓冲区中的数据复制到进程缓冲区中. 一.阻塞IO 进程会阻塞在等待内核准备数据和数据从内核空间复制到用户空间这两个阶段. 二.非阻塞I ...
- 【转】Js获取当前日期时间及其它操作
Js获取当前日期时间及其它操作 原文地址:http://www.cnblogs.com/carekee/articles/1678041.html var myDate = new Date();my ...
- 常用算法2 - 广度优先搜索 & 深度优先搜索 (python实现)
1. 图 定义:图(Graph)是由顶点的有穷非空集合和顶点之间边的集合组成,通常表示为:G(V,E),其中,G表示一个图,V是图G中顶点的集合,E是图G中边的集合. 简单点的说:图由节点和边组成.一 ...