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学习笔记> 网络编程 网络编程就是在两个或两个以上的设备(例如计算机)之间传输数据.程序员所作的事情就是把数据发送到指定的位置,或者接收到指定的数据,这个就 ...
随机推荐
- C# 注销掉事件,解决多播委托链表的问题
c#的事件是多播委托.当绑定多个事件时,事件会依次触发,清除掉注册的委托链表:方法1 C# Code 12345678910111213141516171819202122232425262728 ...
- android数据保存
永久保存数据的方法:1.Shared Preferences 以键值对的形式存储基本数据类型( booleans, floats, ints, longs, and strings),存储的数据在限制 ...
- 【转】Linux中断处理学习笔记
原文网址:http://www.cnblogs.com/GT_Andy/archive/2011/06/21/2086100.html 1.Linux中断的注册与释放: 在<linux/inte ...
- HDU_2043——判断密码是否安全
Problem Description 网上流传一句话:"常在网上飘啊,哪能不挨刀啊-".其实要想能安安心心地上网其实也不难,学点安全知识就可以.首先,我们就要设置一个安全的密码. ...
- FZU 11月月赛D题:双向搜索+二分
/* 双向搜索感觉是个不错的技巧啊 */ 题目大意: 有n的物品(n<=30),平均(两个人得到的物品差不能大于1)分给两个人,每个物品在每个人心目中的价值分别为(vi,wi) 问两人心目中的价 ...
- [置顶] 白话最小边覆盖总结--附加 hdu1151结题报告
刚开始看到这个题目的时候就觉得想法很明了,就是不知道如何去匹配... 去网上看了不少人的解题报告,但是对于刚接触“最小边覆盖”的我来说....还是很困难滴....于是自己又开始一如以往学习“最大独立集 ...
- erlang mnesia 数据库查询
Mnesia是一个分布式数据库管理系统,适合于电信和其它需要持续运行和具备软实时特性的Erlang应用,越来越受关注和使用,但是目前Mnesia资料却不多,很多都只有官方的用户指南.下面的内容将着重说 ...
- switchover和failover
Dataguard中primary和standby间的角色切换包括两种:1. switchoverprimary和standby互换角色,一般都是人为的有计划的,主要用于主机或数据库的升级,不会有数据 ...
- solr索引
solr索引 当我们真正进入到Lucene源代码之中的时候,我们会发现: • Lucene的索引过程,就是按照全文检索的基本过程,将倒排表写成此文件格式的过程. • Lucene的搜索过程,就是按照此 ...
- mongoose--------ORM数据操作框架
数据关系映射:ORM O:object R:relation M:mapping 把对数据库的操作都封装到对象中,操作了对象,就相当于操作了数据库. 安装: npm install mongoose ...