版权声明:

欢迎转载,但请保留文章原始出处

作者:GavinCT

出处:http://www.cnblogs.com/ct2011/p/4002738.html

什么时候可以把解析值赋给对象

一般从网上看到的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 解析注意的更多相关文章

  1. Java用SAX解析XML

    要解析的XML文件:myClass.xml <?xml version="1.0" encoding="utf-8"?> <class> ...

  2. Java XML Dom解析工具

    Java XML Dom解析工具 缩进等 transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); ...

  3. JAVA使用SAX解析XML文件

    在我的另一篇文章(http://www.cnblogs.com/anivia/p/5849712.html)中,通过一个例子介绍了使用DOM来解析XML文件,那么本篇文章通过相同的XML文件介绍如何使 ...

  4. java使用sax解析xml

    目的:解析xml文件,并存入mysql,并且要解析的字段能一一对应.这里解析的是微博的文件,想要利用里面的article和person_id字段. 思路: 为了能得到person_id和article ...

  5. Java中Sax解析XML

    SAX基于事件的解析,解析器在一次读取XML文件中根据读取的数据产生相应的事件,由应用程序实现相应的事件处理逻辑,即它是一种“推”的解析方式:这种解析方法速度快.占用内存少,但是它需要应用程序自己处理 ...

  6. 简单的java使用SAX解析xml

    1.新建一个SAXTest类,继承import org.xml.sax.helpers.DefaultHandler类 package com.qiao.SrpingSource; import or ...

  7. XML SAX解析

    SAX是一种占用内存少且解析速度快的解析器,它采用的是事件驱动,它不需要解析完整个文档,而是按照内容顺序,看文档某个部分是否符合xml语法,如果符合就触发相应的事件.所谓的事件就是些回调方法( cal ...

  8. JavaEE XML SAX解析

    SAX解析XML @author ixenos SAX解析工具 SAX解析工具-  Sun公司提供的.内置在jdk中.org.xml.sax.* 核心的API: SAXParser类: 用于读取和解析 ...

  9. 浅谈 Java Xml 底层解析方式

    XML 使用DTD(document type definition)文档类型来标记数据和定义数据,格式统一且跨平台和语言,已成为业界公认的标准. 目前 XML 描述数据龙头老大的地位渐渐受到 Jso ...

随机推荐

  1. ASP.NET:EntityFramework实现Session

    ASP.NET默认的InProc模式的Session既浪费内存又在网站重启时存在数据丢失问题,SQLServer模式的Session只支持SQL Server又需要命令行配置.使用EntityFram ...

  2. bug、兼容性、适配问题

    1.input   type=“number” 在火狐上限制长度会有问题: 1.maxlength 不管用 2.正则或js匹配限制长度后,给这个input赋值时候末尾三位(有可能是几位,我遇到的是三位 ...

  3. centos7 Mariadb5.5升级到Mariadb10.2

    一次升级过程,在此记录下. 原因:新的项目需要新的数据库版本支持. 升级主要步骤: 备份原数据库 --->卸载mariadb --->添加mariadb国内yum源 --->安装ma ...

  4. struct in_addr 结构体

    struct in_addr 结构体: struct in_addr { in_addr_t s_addr; }; 表示一个32位的IPv4地址. in_addr_t一般为32位的unsigned i ...

  5. json-lib使用——JSONObject与JSONArray

    ps:看这篇博客之前首先要引入工具包json-lib-2.2.2-jdk15.jar 资源链接:百度云:链接:https://pan.baidu.com/s/1o9k7PSu 密码:00lj 一.从O ...

  6. oracle = : := 和变量绑定 oracle通配符和运算符

    这篇是7788凑的:":="是赋值语句 如: l_name :='sky';..."=" 是判断是否相等. 如: if 1=1 then...":&q ...

  7. sqlserver中利用Tran_sql把逗号分隔的字符串拆成临时表

    在与数据库交互的过程中,我们经常需要把一串ID组成的字符串当作参数传给存储过程获取数据.很多时候我们希望把这个字符串转成集合以方便用于in操作. 有两种方式可以方便地把这个以某种符号分隔的ID字符串转 ...

  8. [硬件知识]OP(Over-provisioning)预留空间

    SSD上的OP指的是用户不可操作的容量,大小为实际容量减去用户可用容量,OP区域一般被用于优化操作如:WL,GC和坏块映射等. OP一般分三层(见下图).第一层容量固定为SSD标称容量的7.37%,这 ...

  9. [转]微信小程序之购物数量加减 —— 微信小程序实战商城系列(3)

    本文转自:http://blog.csdn.net/michael_ouyang/article/details/70194144 我们在购买宝贝的时候,购物的数量,经常是我们需要使用的,如下所示: ...

  10. 在C#使用文件监控对象FileSystemWatcher 实现数据同步

    最近在项目中有这么个需求,就是得去实时获取某个在无规律改变的文本文件中的内容.首先想到的是用程序定期去访问这个文件,因为对实时性要求很高,间隔不能超过1S,而且每次获取到文本内容都要去分发给WEB服务 ...