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 ...
随机推荐
- 关于冒泡排序的Java代码实现
一.排序算法的历史: 排序算法的发展历史几乎和计算机的发展历史一样悠久,而且直到今天,世界范围内依然有计算机科学家正在研究着排序的算法,由此可见排序算法的强大魅力. 我们现在介绍的排序算法都是前任 ...
- 开源微信支付SDK
应该有一年多没在博客园上写文章了,毕竟是一个记录自己技术成长的平台,没能将写博客长期坚持下来,说起来也是挺惭愧的.对于自己的近况而言,确实平常加班也比较多,时间会比较压缩,所以到后来博客也基本停止了更 ...
- Java学习之路(九):Map集合
Map集合概述和特点 Map是属于java.util的一个接口Map<k,v> k:映射所维护的键的类型 v:映射值的类型 Map是将键映射到值的对象.一个映射不能包含重复的键:每个键最多 ...
- django第四课 标签的用法(if/else、for、ifequal、过滤器、注释等)
if/else {% if %} <p>内容</P> {% endif %} {% else %}是可选标签 {% if %} <p>内容</P> {% ...
- 解决chrome,下载在文件夹中显示,调用错误的关联程序
https://blog.csdn.net/qq_32337527/article/details/81778732?utm_source=blogxgwz0
- Spring+Druid+SpringMVC的搭建(附Demo)
最近公司事情比较少,便想利用这段空闲时间做一个自己的博客. 前端界面已经搞好,感谢杨姐的模板,自己稍微把模板没有的模块给补全了. 今天便开始自己的SSM框架搭建,数据库链接是采用数据库连接池.先上个项 ...
- go语言的unsafe包(转)
The unsafe Package in Golang Golang的unsafe包是一个很特殊的包. 为什么这样说呢? 本文将详细解释. 来自go语言官方文档的警告 unsafe包的文档是这么说的 ...
- 删除none 的images报错 image has dependent child images 解决办法
这个错是因为在要删除的images之后创建了该images的父images 方法: docker image inspect --format='{{.RepoTags}} {{.Id}} {{.Pa ...
- php的isset()和empty()区别
转载:http://www.cnblogs.com/ndxsdhy/archive/2011/04/02/2003193.html 1.isset()函数 一般用来检测变量是否设置 (是否已经赋值) ...
- 如何在.Net Core MVC中为动态表单开启客户端验证
非Core中的请参照: MVC的验证 jquery.validate.unobtrusive mvc验证jquery.unobtrusive-ajax 参照向动态表单增加验证 页面引入相关JS: &l ...