Java学习笔记--xml构造与解析之Sax的使用
汇总:xml的构造与解析 http://www.cnblogs.com/gnivor/p/4624058.html
参考资料:http://www.iteye.com/topic/763895
利用SAX存储XML(一般不这么用)
import java.io.FileNotFoundException;
import java.io.FileOutputStream; import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult; import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl; public class MySax { public static void main(String[] args) throws FileNotFoundException, TransformerConfigurationException, SAXException{
MySax mysax = new MySax();
mysax.generate();
} //生成xml文档的函数
public void generate() throws FileNotFoundException, TransformerConfigurationException, SAXException{
Result resultXml = new StreamResult(new FileOutputStream("c:\\person.xml")); //输出到person.xml SAXTransformerFactory sff = (SAXTransformerFactory)SAXTransformerFactory.newInstance();
TransformerHandler th = sff.newTransformerHandler();
th.setResult(resultXml); Transformer transformer = th.getTransformer();
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); //编码格式是UTF-8
transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //换行
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");// 是否忽略xml声明 AttributesImpl attr = new AttributesImpl(); th.startDocument(); //开始xml文档 th.startElement("", "", "person", attr); //定义person节点 th.startElement("", "", "name", attr); //定义name节点
th.characters("张三".toCharArray(), 0, "张三".length());
th.endElement("", "", "name"); //结束name节点 th.startElement("", "", "age", attr); //定义age节点
th.characters("29".toCharArray(), 0, "29".length());
th.endElement("", "", "age"); //结束age节点 th.startElement("", "", "gender", attr); //定义gender节点
th.characters("男".toCharArray(), 0, "男".length());
th.endElement("", "", "gender"); //结束gender节点 th.endElement("", "", "person"); //结束person节点 th.endDocument(); //结束xml文档
}
}
利用SAX对XML进行解析
要解析的文件
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book id="12">
<name>thinking in java</name>
<price>85.5</price>
</book>
<book id="15">
<name>Spring in Action</name>
<price>39.0</price>
</book>
</books>
解析方法
xml文件被Sax解析器载入,由于Sax解析是按照xml文件的顺序来解析。
当读入<?xml.....>时,会调用startDocument()方法,
当读入<books>的时候,由于它是个ElementNode,所以会调用startElement(String uri, String localName, String qName, Attributes attributes) 方法。
注意:上面方法第二个参数就是节点的名称.由于有些环境不一样,有时候第二个参数有可能为空,所以可以使用第三个参数,因此在解析前,先调用一下看哪个参数能用。第4个参数是这个节点的属性。
我们不需要<books>这个节点,所以从<book>这个节点开始,也就是图中1的位置。
当读入时,调用startElement(....)方法,由于只有一个属性id,可以通过attributes.getValue(0)来得到,
然后在图中标明2的地方会调用characters(char[] ch, int start, int length)方法,不要以为那里是空白,Sax解析器可不那么认为,Sax解析器会把它认为是一个TextNode。但是这个空白不是我们想要的数据,我们是想要<name>节点下的文本信息。这就要定义一个记录当上一节点的名称的TAG,在characters(.....)方法中,判断当前节点是不是name,是再取值,才能取到thinking in java。具体见代码。
Book
class Book {
private int id;
private String name;
private float price; public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setPrice(float price) {
this.price = price;
}
@Override
public String toString(){
return "id:"+ this.id+", 书名:"+this.name+", 价格:"+this.price;
}
}
SaxParseService
class SaxParseService extends DefaultHandler{
private List<Book> books = null;
private Book book = null;
private String preTag = null;//作用是记录解析时的上一个节点名称 public List<Book> getBooks(InputStream xmlStream) throws Exception{
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
SaxParseService handler = new SaxParseService();
parser.parse(xmlStream, handler); //对文件流进行解析
return handler.books; //返回结果
} //第1个分析点事件方法。在该方法中创建了用于保存 转换结果的List<Book>对象
@Override
public void startDocument() throws SAXException {
books = new ArrayList<Book>();
} //第2个分析点事件方法。SAX引擎分析到每一个<book>元素时,在该方法中都会创建一个Book对象
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if("book".equals(qName)){
book = new Book();
book.setId(Integer.parseInt(attributes.getValue(0)));
}
preTag = qName;//将正在解析的节点名称赋给preTag
} //第3个分析点事件方法。当SAX引擎每分析完一个XML元素之后,会将当前book加入到Books列表之中
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
if("book".equals(qName)){
books.add(book);
book = null;
}
preTag = null; /* 当解析结束时置为空。这里很重要,例如,当图中画3的位置结束后,会调用这个方法
* ,如果这里不把preTag置为null,根据startElement(....)方法,preTag的值还是book,当文档顺序读到图
* 中标记4的位置时,会执行characters(char[] ch, int start, int length)这个方法,
* 而characters(....)方法判断preTag!=null,会执行if判断的代码,
* 这样就会把空值赋值给book,这不是我们想要的。
* */
} //第4个分析点事件方法。分析每一个book元素,并将book元素的属性保存在Book对象之中
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
if(preTag!=null){
String content = new String(ch,start,length);
if("name".equals(preTag)){
book.setName(content);
}else if("price".equals(preTag)){
book.setPrice(Float.parseFloat(content));
}
}
}
}
测试类
public class BookSax {
public static void main(String[] args) throws Throwable{
BookSax booksax = new BookSax();
booksax.testSAX();
}
public void testSAX() throws Throwable{
SaxParseService sax = new SaxParseService();
File file = new File("F:\\测试TXT\\book.xml");
FileInputStream input = new FileInputStream(file); List<Book> books = sax.getBooks(input);
for(Book book : books){
System.out.println(book.toString());
}
}
}
运行结果:
id:12, 书名:thinking in java, 价格:85.5
id:15, 书名:Spring in Action, 价格:39.0
Java学习笔记--xml构造与解析之Sax的使用的更多相关文章
- Java学习笔记XML(3)
XML简介 XML即可扩展的标记语言.因此该语言中所有的标签都是没有预先定义的,开发者可以自己随意的指定. 目前为止所有的标记的语言都属于开源的语言.由W3C组织进行一个基本的维护. 因此大家学习这些 ...
- Java学习笔记——XML入门
以下内容来自网络 什么是 XML? XML 指可扩展标记语言(EXtensible Markup Language). XML 是一种很像HTML的标记语言. XML 的设计宗旨是传输数据,而不是显示 ...
- Java学习笔记4
Java学习笔记4 1. JDK.JRE和JVM分别是什么,区别是什么? 答: ①.JDK 是整个Java的核心,包括了Java运行环境.Java工具和Java基础类库. ②.JRE(Java Run ...
- Java学习笔记之---API的应用
Java学习笔记之---API的应用 (一)Object类 java.lang.Object 类 Object 是类层次结构的根类.每个类都使用 Object 作为超类.所有对象(包括数组)都实现这个 ...
- Java学习笔记(04)
Java学习笔记(04) 如有不对或不足的地方,请给出建议,谢谢! 一.对象 面向对象的核心:找合适的对象做合适的事情 面向对象的编程思想:尽可能的用计算机语言来描述现实生活中的事物 面向对象:侧重于 ...
- 0032 Java学习笔记-类加载机制-初步
JVM虚拟机 Java虚拟机有自己完善的硬件架构(处理器.堆栈.寄存器等)和指令系统 Java虚拟机是一种能运行Java bytecode的虚拟机 JVM并非专属于Java语言,只要生成的编译文件能匹 ...
- 《Java学习笔记(第8版)》学习指导
<Java学习笔记(第8版)>学习指导 目录 图书简况 学习指导 第一章 Java平台概论 第二章 从JDK到IDE 第三章 基础语法 第四章 认识对象 第五章 对象封装 第六章 继承与多 ...
- 0013 Java学习笔记-面向对象-static、静态变量、静态方法、静态块、单例类
static可以修饰哪些成员 成员变量---可以修饰 构造方法---不可以 方法---可以修饰 初始化块---可以修饰 内部类(包括接口.枚举)---可以修饰 总的来说:静态成员不能访问非静态成员 静 ...
- 20145330第十周《Java学习笔记》
20145330第十周<Java学习笔记> 网络编程 网络编程就是在两个或两个以上的设备(例如计算机)之间传输数据.程序员所作的事情就是把数据发送到指定的位置,或者接收到指定的数据,这个就 ...
随机推荐
- PHP Java
http://my.oschina.net/lajp/blog/5121 http://blog.163.com/lijianwei_123/blog/static/18489289120115244 ...
- cf D. Broken Monitor
http://codeforces.com/contest/370/problem/D 题意:输入一张图,上面只有两个字符'w'和‘.’ ,如果可以用一个正方形把所有的‘w’围起来,所有的‘w’都在正 ...
- op编译信赖的库
Table of known prerequisites and their corresponding packages Here's a table with the package name f ...
- [LeetCode] 11. Container With Most Water My Submissions Question 解题思路
Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai). ...
- hadoop2.2.0 MapReduce求和并排序
javabean必须实现WritableComparable接口,并实现该接口的序列化,反序列话和比较方法 package com.my.hadoop.mapreduce.sort; import j ...
- java类的加载顺序
related URL: http://www.cnblogs.com/guoyuqiangf8/archive/2012/10/31/2748909.html Parent Class: packa ...
- cnBlogs_代码着色
一个程序员当然希望写出来的代码不仅质量上好,而且看上去也很好.以前在网络上看见别人写的代码,着色以及背景都好极了,很是羡慕,但就是不知道如何设置 --------------------------- ...
- Django之模板语言
一.模板语言介绍 模板语言渲染的整个过程其实就是将html转换成函数,并为该函数提供全局变量,然后执行该函数 二.模板语言的语法 模板中也有自己的语言,该语言可以实现数据展示 # 业务请求处理做的页面 ...
- 通过layout实现可拖拽自动排序的UICollectionView
文/CenturyGuo(简书作者)原文链接:http://www.jianshu.com/p/8d1bf1838882著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. Translat ...
- jquery之图片上传
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...