汇总:xml的构造与解析 http://www.cnblogs.com/gnivor/p/4624058.html

参考资料:http://www.iteye.com/topic/763895

利用SAX存储XML(一般不这么用)

  1. import java.io.FileNotFoundException;
  2. import java.io.FileOutputStream;
  3.  
  4. import javax.xml.transform.OutputKeys;
  5. import javax.xml.transform.Result;
  6. import javax.xml.transform.Transformer;
  7. import javax.xml.transform.TransformerConfigurationException;
  8. import javax.xml.transform.sax.SAXTransformerFactory;
  9. import javax.xml.transform.sax.TransformerHandler;
  10. import javax.xml.transform.stream.StreamResult;
  11.  
  12. import org.xml.sax.SAXException;
  13. import org.xml.sax.helpers.AttributesImpl;
  14.  
  15. public class MySax {
  16.  
  17. public static void main(String[] args) throws FileNotFoundException, TransformerConfigurationException, SAXException{
  18. MySax mysax = new MySax();
  19. mysax.generate();
  20. }
  21.  
  22. //生成xml文档的函数
  23. public void generate() throws FileNotFoundException, TransformerConfigurationException, SAXException{
  24. Result resultXml = new StreamResult(new FileOutputStream("c:\\person.xml")); //输出到person.xml
  25.  
  26. SAXTransformerFactory sff = (SAXTransformerFactory)SAXTransformerFactory.newInstance();
  27. TransformerHandler th = sff.newTransformerHandler();
  28. th.setResult(resultXml);
  29.  
  30. Transformer transformer = th.getTransformer();
  31. transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); //编码格式是UTF-8
  32. transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //换行
  33. transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");// 是否忽略xml声明
  34.  
  35. AttributesImpl attr = new AttributesImpl();
  36.  
  37. th.startDocument(); //开始xml文档
  38.  
  39. th.startElement("", "", "person", attr); //定义person节点
  40.  
  41. th.startElement("", "", "name", attr); //定义name节点
  42. th.characters("张三".toCharArray(), 0, "张三".length());
  43. th.endElement("", "", "name"); //结束name节点
  44.  
  45. th.startElement("", "", "age", attr); //定义age节点
  46. th.characters("29".toCharArray(), 0, "29".length());
  47. th.endElement("", "", "age"); //结束age节点
  48.  
  49. th.startElement("", "", "gender", attr); //定义gender节点
  50. th.characters("男".toCharArray(), 0, "男".length());
  51. th.endElement("", "", "gender"); //结束gender节点
  52.  
  53. th.endElement("", "", "person"); //结束person节点
  54.  
  55. th.endDocument(); //结束xml文档
  56. }
  57. }

利用SAX对XML进行解析

要解析的文件

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <books>
  3. <book id="12">
  4. <name>thinking in java</name>
  5. <price>85.5</price>
  6. </book>
  7. <book id="15">
  8. <name>Spring in Action</name>
  9. <price>39.0</price>
  10. </book>
  11. </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

  1. class Book {
  2. private int id;
  3. private String name;
  4. private float price;
  5.  
  6. public void setId(int id) {
  7. this.id = id;
  8. }
  9. public void setName(String name) {
  10. this.name = name;
  11. }
  12. public void setPrice(float price) {
  13. this.price = price;
  14. }
  15. @Override
  16. public String toString(){
  17. return "id:"+ this.id+", 书名:"+this.name+", 价格:"+this.price;
  18. }
  19. }

SaxParseService

  1. class SaxParseService extends DefaultHandler{
  2. private List<Book> books = null;
  3. private Book book = null;
  4. private String preTag = null;//作用是记录解析时的上一个节点名称
  5.  
  6. public List<Book> getBooks(InputStream xmlStream) throws Exception{
  7. SAXParserFactory factory = SAXParserFactory.newInstance();
  8. SAXParser parser = factory.newSAXParser();
  9. SaxParseService handler = new SaxParseService();
  10. parser.parse(xmlStream, handler); //对文件流进行解析
  11. return handler.books; //返回结果
  12. }
  13.  
  14. //第1个分析点事件方法。在该方法中创建了用于保存 转换结果的List<Book>对象
  15. @Override
  16. public void startDocument() throws SAXException {
  17. books = new ArrayList<Book>();
  18. }
  19.  
  20. //第2个分析点事件方法。SAX引擎分析到每一个<book>元素时,在该方法中都会创建一个Book对象
  21. @Override
  22. public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
  23. if("book".equals(qName)){
  24. book = new Book();
  25. book.setId(Integer.parseInt(attributes.getValue(0)));
  26. }
  27. preTag = qName;//将正在解析的节点名称赋给preTag
  28. }
  29.  
  30. //第3个分析点事件方法。当SAX引擎每分析完一个XML元素之后,会将当前book加入到Books列表之中
  31. @Override
  32. public void endElement(String uri, String localName, String qName)
  33. throws SAXException {
  34. if("book".equals(qName)){
  35. books.add(book);
  36. book = null;
  37. }
  38. preTag = null;
  39.  
  40. /* 当解析结束时置为空。这里很重要,例如,当图中画3的位置结束后,会调用这个方法
  41. * ,如果这里不把preTag置为null,根据startElement(....)方法,preTag的值还是book,当文档顺序读到图
  42. * 中标记4的位置时,会执行characters(char[] ch, int start, int length)这个方法,
  43. * 而characters(....)方法判断preTag!=null,会执行if判断的代码,
  44. * 这样就会把空值赋值给book,这不是我们想要的。
  45. * */
  46. }
  47.  
  48. //第4个分析点事件方法。分析每一个book元素,并将book元素的属性保存在Book对象之中
  49. @Override
  50. public void characters(char[] ch, int start, int length) throws SAXException {
  51. if(preTag!=null){
  52. String content = new String(ch,start,length);
  53. if("name".equals(preTag)){
  54. book.setName(content);
  55. }else if("price".equals(preTag)){
  56. book.setPrice(Float.parseFloat(content));
  57. }
  58. }
  59. }
  60. }

测试类

  1. public class BookSax {
  2. public static void main(String[] args) throws Throwable{
  3. BookSax booksax = new BookSax();
  4. booksax.testSAX();
  5. }
  6. public void testSAX() throws Throwable{
  7. SaxParseService sax = new SaxParseService();
  8. File file = new File("F:\\测试TXT\\book.xml");
  9. FileInputStream input = new FileInputStream(file);
  10.  
  11. List<Book> books = sax.getBooks(input);
  12. for(Book book : books){
  13. System.out.println(book.toString());
  14. }
  15. }
  16. }

运行结果:

id:12, 书名:thinking in java, 价格:85.5
id:15, 书名:Spring in Action, 价格:39.0

Java学习笔记--xml构造与解析之Sax的使用的更多相关文章

  1. Java学习笔记XML(3)

    XML简介 XML即可扩展的标记语言.因此该语言中所有的标签都是没有预先定义的,开发者可以自己随意的指定. 目前为止所有的标记的语言都属于开源的语言.由W3C组织进行一个基本的维护. 因此大家学习这些 ...

  2. Java学习笔记——XML入门

    以下内容来自网络 什么是 XML? XML 指可扩展标记语言(EXtensible Markup Language). XML 是一种很像HTML的标记语言. XML 的设计宗旨是传输数据,而不是显示 ...

  3. Java学习笔记4

    Java学习笔记4 1. JDK.JRE和JVM分别是什么,区别是什么? 答: ①.JDK 是整个Java的核心,包括了Java运行环境.Java工具和Java基础类库. ②.JRE(Java Run ...

  4. Java学习笔记之---API的应用

    Java学习笔记之---API的应用 (一)Object类 java.lang.Object 类 Object 是类层次结构的根类.每个类都使用 Object 作为超类.所有对象(包括数组)都实现这个 ...

  5. Java学习笔记(04)

    Java学习笔记(04) 如有不对或不足的地方,请给出建议,谢谢! 一.对象 面向对象的核心:找合适的对象做合适的事情 面向对象的编程思想:尽可能的用计算机语言来描述现实生活中的事物 面向对象:侧重于 ...

  6. 0032 Java学习笔记-类加载机制-初步

    JVM虚拟机 Java虚拟机有自己完善的硬件架构(处理器.堆栈.寄存器等)和指令系统 Java虚拟机是一种能运行Java bytecode的虚拟机 JVM并非专属于Java语言,只要生成的编译文件能匹 ...

  7. 《Java学习笔记(第8版)》学习指导

    <Java学习笔记(第8版)>学习指导 目录 图书简况 学习指导 第一章 Java平台概论 第二章 从JDK到IDE 第三章 基础语法 第四章 认识对象 第五章 对象封装 第六章 继承与多 ...

  8. 0013 Java学习笔记-面向对象-static、静态变量、静态方法、静态块、单例类

    static可以修饰哪些成员 成员变量---可以修饰 构造方法---不可以 方法---可以修饰 初始化块---可以修饰 内部类(包括接口.枚举)---可以修饰 总的来说:静态成员不能访问非静态成员 静 ...

  9. 20145330第十周《Java学习笔记》

    20145330第十周<Java学习笔记> 网络编程 网络编程就是在两个或两个以上的设备(例如计算机)之间传输数据.程序员所作的事情就是把数据发送到指定的位置,或者接收到指定的数据,这个就 ...

随机推荐

  1. 用MarkDown来排版写作

    Latex排版系统太复杂,MD很好用,微软开源了一套Madoko的开源在线MD编辑器,它提供了一台MD扩展,可以生成PDF(中间先生成Tex,再生成的PDF),幻灯片还有html.非常方便.写作,写p ...

  2. Linux标准输入、输出和错误和文件重定向(转) --- good

    标准输入.输出和错误 当我们在shell中执行命令的时候,每个进程都和三个打开的文件相联系,并使用文件描述符来引用这些文件.由于文件描述符不容易记忆,shell同时也给出了相应的文件名.下面就是这些文 ...

  3. vim 中按键映射问题

    按键映射关键字的组成开始让我摸不着头脑,查了资料,然后来做一个log 按键绑定命令:模式前缀(缺省为normal) + 递归前缀(缺省为空) + map 前缀表示生效范围,递归前缀表示是否递归查找命令 ...

  4. 【Python基础】计算项目代码行数

    统计代码行数 # coding: utf-8 import os import sys import time def get_line_count(file_path): ""& ...

  5. Github 开源编辑器 ATOM 已开放下载

    Update:2014-09-08 Atom 于5月6日正式开放下载(遗憾的是只有 MAC 版本),并且在 MIT 协义下开源,从界面可以看出,这款软件很像 Sublime Text,不过由于她的开源 ...

  6. 使用带Arduino IDE & WIZ820io的ATmega1284P

    使用带Arduino IDE & WIZ820io的ATmega1284P 2013/07/04 | Filed under:   IO模块 and tagged with:   arduin ...

  7. [nagios监控] NRPE: Unable to read output 的原因及排除

    nrpe被监控端运行定义命令正常,监控端运行 #/usr/local/nagios/libexec/check_nrpe -H 117.121.9.200 -c check_oracle_tables ...

  8. wm命令用法及LCD显示图标大小不正常时解决的方法

    注:Android 4.3引入的wm工具 wm命令及使用方法: 系统说明: usage: wm [subcommand] [options]                               ...

  9. mybati之#与$的区别

    $是用于sql的拼接: //因为user_name是String类型,所以在sql中加上单引号,需要手动的判断数据类型,value是如果没有指定参数的话,value就是默认参数名称,获取穿的参数就是: ...

  10. 一个小的程序--实现中英文切换(纯css)

    <!doctype html><html lang="en"> <head> <meta charset="UTF-8" ...