`
SunnyYoona
  • 浏览: 364478 次
社区版块
存档分类
最新评论

[Java开发之路](11)SAX解析XML文档

 
阅读更多


1. 简介

Dom解析功能强大,可增删改查,操作时会将XML文档读到内存,因此适用于小文档;
SAX解析是从头到尾逐行逐个元素解析,修改较为不便,但适用于只读的大文档;

SAX采用事件驱动的方式解析XML。套用网友的解释:如同在电影院看电影一样,从头到尾看一遍,不能回退(Dom可来来回回读取),在看电影的过程中,每遇到一个情节,都会调用大脑去接收处理这些信息。SAX也是相同的原理,每遇到一个元素节点,都会调用相应的方法来处理。在SAX的解析过程中,读取到文档开头、文档结尾,元素的开头和元素结尾都会调用相应方法,我们可以在这些方法中进行相应事件处理。

对应方法:
public void startDocument() throws SAXException {
}
public void endDocument() throws SAXException {
}
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
}
public void endElement(String uri, String localName, String qName) throws SAXException {
}

我们还需一个方法来处理元素节点中间的文本节点(我们常误以为元素节点的文本值)
public void characters(char[] ch, int start, int length) throws SAXException {
}

2. 解析

解析步骤:

(1)通过SAXParserFactory的静态方法newInstance()方法获取SAXParserFactory实例对象factory
SAXParserFactory factory = SAXParserFactory.newInstance();
(2)通过SAXParserFactory实例的newSAXParser()方法返回SAXParser实例parser
SAXParser parser = factory.newSAXParser();
(3)创建一个类继承DefaultHandler,重写其中的一些方法进行业务处理
package com.qunar.handler;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class SAXParserHandler extends DefaultHandler{
// 用来标示解析开始
@Override
public void startDocument() throws SAXException {
}
// 用来标示解析结束
@Override
public void endDocument() throws SAXException {
}
// 用来遍历XML文件的开始标签
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes);
}
// 用来遍历XML文件的结束标签
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
super.endElement(uri, localName, qName);
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
super.characters(ch, start, length);
}
}
(4)创建Handler类对象实例
// 定义SAXParserHandler对象
SAXParserHandler handler = new SAXParserHandler();
(5)解析XML文档
saxParser.parse(path, handler);


以下代码均使用本XML文档:
<?xml version="1.0" encoding="utf-8"?><bookstore>
<book category="Java">
<title lang="chi">Java多线程编程核心技术</title>
<author>高洪岩</author>
<year>2015</year>
<price>69.00</price>
</book>
<book category="C++">
<title lang="en">Effective C++: 55 Specific Ways to Improve Your Programs and Designs</title>
<author>Scott Meyers</author>
<year>2006</year>
<price>58.00</price>
</book>
<book category="Web">
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<year>2016</year>
<price>39.95</price>
</book>
</bookstore>

  • 3. 具体实例:
    package com.qunar.handler;
    import org.xml.sax.Attributes;
    import org.xml.sax.SAXException;
    import org.xml.sax.helpers.DefaultHandler;
    public class SAXParserHandler extends DefaultHandler{
    private int bookIndex = 0;
    // 用来标示解析开始
    @Override
    public void startDocument() throws SAXException {
    System.out.println("SAX解析开始...");
    }
    // 用来标示解析结束
    @Override
    public void endDocument() throws SAXException {
    System.out.println("SAX解析结束...");
    }
    // 用来遍历XML文件的开始标签
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
    // 调用DefaultHandler类的startElement方法
    super.startElement(uri, localName, qName, attributes);
    // 开始解析book元素节点
    if(qName.equals("book")){
    ++ bookIndex;
    System.out.println("开始解析第" + bookIndex + "本书...");
    // 已知book元素节点下的属性名称,根据属性名称获取属性值
    /*String value = attributes.getValue("category");
    System.out.println("value->"+value);*/
    // 不知道book元素节点下的属性名称以及个数
    int size = attributes.getLength();
    for(int i = 0;i < size;++i){
    System.out.println(attributes.getQName(i) + ":" + attributes.getValue(i));
    }//for
    }//if
    else if(!qName.equals("bookstore")){
    System.out.print(qName + ":");
    }//else
    }
    // 用来遍历XML文件的结束标签
    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
    super.endElement(uri, localName, qName);
    // 判断一本书是否解析完
    if(qName.equals("book")){
    System.out.println("结束解析第" + bookIndex + "本书...");
    }//if
    }
    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
    super.characters(ch, start, length);
    String text = new String(ch, start, length);
    if(!text.trim().equals("")){
    System.out.println(text);
    }//if
    }
    }

    package com.qunar.xml;
    import java.io.IOException;
    import javax.xml.parsers.ParserConfigurationException;
    import javax.xml.parsers.SAXParser;
    import javax.xml.parsers.SAXParserFactory;
    import org.xml.sax.SAXException;
    import com.qunar.handler.SAXParserHandler;
    /**
    * SAX方式解析XML文档
    * @author sjf0115
    *
    */
    public class SAXXMLCode {
    public static void main(String[] args) {
    String path = "D:\\bookstore.xml";
    try {
    // 通过SAXParserFactory的静态方法newInstance()方法获取SAXParserFactory实例对象factory
    SAXParserFactory factory = SAXParserFactory.newInstance();
    // 通过SAXParserFactory实例的newSAXParser()方法返回SAXParser实例parser
    SAXParser saxParser = factory.newSAXParser();
    // 定义SAXParserHandler对象
    SAXParserHandler handler = new SAXParserHandler();
    // 解析XML文档
    saxParser.parse(path, handler);
    } catch (ParserConfigurationException e) {
    e.printStackTrace();
    } catch (SAXException e) {
    e.printStackTrace();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }

    运行结果:

    SAX解析开始...
    开始解析第1本书...
    category:Java
    title:Java多线程编程核心技术
    author:高洪岩
    year:2015
    price:69.00
    结束解析第1本书...
    开始解析第2本书...
    category:C++
    title:EffectiveC++:55SpecificWaystoImproveYourProgramsandDesigns
    author:ScottMeyers
    year:2006
    price:58.00
    结束解析第2本书...
    开始解析第3本书...
    category:Web
    title:LearningXML
    author:ErikT.Ray
    year:2016
    price:39.95
    结束解析第3本书...
    SAX解析结束...

    4. 解析并储存于对象中

    package com.qunar.bean;
    /**
    * book实体类
    * @author sjf0115
    *
    */
    public class Book {
    private String category;
    private String title;
    private String author;
    private String year;
    private String price;
    private String lang;
    public String getCategory() {
    return category;
    }
    public void setCategory(String category) {
    this.category = category;
    }
    public String getTitle() {
    return title;
    }
    public void setTitle(String title) {
    this.title = title;
    }
    public String getAuthor() {
    return author;
    }
    public void setAuthor(String author) {
    this.author = author;
    }
    public String getYear() {
    return year;
    }
    public void setYear(String year) {
    this.year = year;
    }
    public String getPrice() {
    return price;
    }
    public void setPrice(String price) {
    this.price = price;
    }
    public String getLang() {
    return lang;
    }
    public void setLang(String lang) {
    this.lang = lang;
    }
    @Override
    public String toString() {
    return "category:" + category + " lang:" + lang + " title:" + title + " author:" + author + " year:" + year + " price:" + price;
    }
    }

    package com.qunar.handler;
    import java.util.ArrayList;
    import java.util.List;
    import org.xml.sax.Attributes;
    import org.xml.sax.SAXException;
    import org.xml.sax.helpers.DefaultHandler;
    import com.qunar.bean.Book;
    public class SAXParserHandler extends DefaultHandler{
    private Book book;
    private int bookIndex = 0;
    // 节点文本内容
    private String text;
    private List<Book> bookList = new ArrayList<Book>();
    public List<Book> getBookList() {
    return bookList;
    }
    // 用来标示解析开始
    @Override
    public void startDocument() throws SAXException {
    System.out.println("SAX解析开始...");
    }
    // 用来标示解析结束
    @Override
    public void endDocument() throws SAXException {
    System.out.println("SAX解析结束...");
    }
    // 用来遍历XML文件的开始标签
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
    // 调用DefaultHandler类的startElement方法
    super.startElement(uri, localName, qName, attributes);
    // 开始解析book元素节点
    if(qName.equals("book")){
    // 创建一个book对象
    book = new Book();
    ++ bookIndex;
    System.out.println("开始解析第" + bookIndex + "本书...");
    int size = attributes.getLength();
    for(int i = 0;i < size;++i){
    String attr = attributes.getQName(i);
    // 属性category
    if(attr.equals("category")){
    book.setCategory(attributes.getValue(i));
    }//if
    }//for
    }//if
    // 用于遍历title节点中的属性
    else if(qName.equals("title")){
    int size = attributes.getLength();
    for(int i = 0;i < size;++i){
    String attr = attributes.getQName(i);
    // 属性category
    if(attr.equals("lang")){
    book.setLang(attributes.getValue(i));
    }//if
    }//for
    }//else
    }
    // 用来遍历XML文件的结束标签
    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
    super.endElement(uri, localName, qName);
    // 判断一本书是否解析完
    if(qName.equals("book")){
    bookList.add(book);
    book = null;
    System.out.println("结束解析第" + bookIndex + "本书...");
    }//if
    else if(qName.equals("title")){
    book.setTitle(text);
    }//else
    else if(qName.equals("author")){
    book.setAuthor(text);
    }//else
    else if(qName.equals("year")){
    book.setYear(text);
    }//else
    else if(qName.equals("price")){
    book.setPrice(text);
    }//else
    }
    // 文本值
    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
    super.characters(ch, start, length);
    text = new String(ch, start, length);
    }
    }

    package com.qunar.xml;
    import java.io.IOException;
    import java.util.List;
    import javax.xml.parsers.ParserConfigurationException;
    import javax.xml.parsers.SAXParser;
    import javax.xml.parsers.SAXParserFactory;
    import org.xml.sax.SAXException;
    import com.qunar.bean.Book;
    import com.qunar.handler.SAXParserHandler;
    /**
    * SAX方式解析XML文档
    * @author sjf0115
    *
    */
    public class SAXXMLCode {
    public static void main(String[] args) {
    String path = "D:\\bookstore.xml";
    try {
    // 通过SAXParserFactory的静态方法newInstance()方法获取SAXParserFactory实例对象factory
    SAXParserFactory factory = SAXParserFactory.newInstance();
    // 通过SAXParserFactory实例的newSAXParser()方法返回SAXParser实例parser
    SAXParser saxParser = factory.newSAXParser();
    // 定义SAXParserHandler对象
    SAXParserHandler handler = new SAXParserHandler();
    // 解析XML文档
    saxParser.parse(path, handler);
    // 得到遍历结果
    List<Book> bookList = handler.getBookList();
    System.out.println("遍历结果:");
    for (Book book : bookList) {
    System.out.println(book);
    }//for
    } catch (ParserConfigurationException e) {
    e.printStackTrace();
    } catch (SAXException e) {
    e.printStackTrace();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }

    运行结果:

    SAX解析开始...
    开始解析第1本书...
    结束解析第1本书...
    开始解析第2本书...
    结束解析第2本书...
    开始解析第3本书...
    结束解析第3本书...
    SAX解析结束...
    遍历结果:
    category:Javalang:chititle:Java多线程编程核心技术author:高洪岩year:2015price:69.00
    category:C++lang:entitle:EffectiveC++:55SpecificWaystoImproveYourProgramsandDesignsauthor:ScottMeyersyear:2006price:58.00
    category:Weblang:entitle:LearningXMLauthor:ErikT.Rayyear:2016price:39.95



    分享到:
    评论

    相关推荐

      Java SAX解析Xml文档Demo

      Java SAX解析Xml Demo(详细注释)

      JAVA 解析XML生成XML文档实例

      JAVA 解析XML和生成XML文档源码。比较全 1.DOM生成和解析XML文档 2.SAX生成和解析XML文档 3.DOM4J生成和解析XML文档 4.JDOM生成和解析XML

      使用DOM解析XML和使用SAX解析XML

      java学习笔记——使用DOM解析XML和使用SAX解析XML

      Java使用sax、dom、dom4j解析xml文档

      Java使用sax、dom、dom4j解析xml文档的代码,包含dom4j的jar包。

      javaSAX方式解析xml文档

      java从服务器读取xml文件并以SAX方式解析附带(服务器与解析源码)

      SAX解析XML源码及文档

      android解析XML 文档及源码 大多数与XML 相关的Java API 在Android 上得到了完全支持,在Android 上可以创建功能强大的移动应用程序,而在Android 上解析XML的技术有三种DOM、SAX、PULL。

      XML-java.rar_XML SAX_sax_sax xml_sax 解析 xml_xml using dom

      使用java语言对XML文档进行解析的示例,包括DOM,SAX方式,并包括使用jdom和jom4j框架进行XML解析或生成XML文档

      java解析XML文件

      java解析XML文件java解析XML文件java解析XML文件java解析XML文件java解析XML文件java解析XML文件

      Java解析XML文档(二):sax读取xml文件导出excel

      NULL 博文链接:https://suky.iteye.com/blog/621169

      Java 解析xml文档

      Java 解析xml文档(SAX,DOM,DOM4J)工程源代码。

      Java解析XML的jar包+四种解析方法

      java解析xml的四种方法的比较,还有四种方法所用到的jar包 附带程序例子 1.DOM生成和解析XML文档 2.SAX生成和解析XML文档 3.DOM4J生成和解析XML文档 4.JDOM生成和解析XML

      使用Sax技术读XML文档:SaxReaderXML.rar

      使用Sax技术读XML文档:SaxReaderXML.rar

      4种解析xml文件 实例

      Java解析XML的四种方法 1. DOM生成和解析XML文档 2. SAX生成和解析XML文档 3. DOM4J生成和解析XML文档 4. JDOM生成和解析XML

      java的XML四种解析方法汇总

      JAVA xml 的四种解析方式,(1)Dom生成和解析XML文档 (2)SAX生成和解析XML文档(3)DOM4J生成和解析XML文档 (4)JDOM生成和解析XML

      java解析xml及4种常用解析比较

      SAX解析器采用了基于事件的模型,它在解析XML文档的时候可以触发一系列的事件,当发现给定的tag的时候,它可以激活一个回调方法,告诉该方法制定的标签已经找到。SAX对内存的要求通常会比较低,因为它让开发人员...

      java xml文件解析

      java xml文件DOM、SAX、DOM4j四种解析方式与性能对比。

      android xml解析1

      在用SAX解析xml文档时候,在读取到文档开始和结束标签时候就会回调一个事件,在读取到其他节点与内容时候也会回调一个事件。在SAX接口中,事件源是org.xml.sax包中的XMLReader,它通过parser()方法来解析XML文档,并...

      XML必知必会:Java、C#、Python多种语言解析XML文档

      解析XML文档概述、DOM解析XML、SAX解析XML 第8章 Java语言解析XML DOM4J概述、示例:遍历节点、示例:插入节点、示例:删除节点 第9章 Python语言解析XML ElementTree模块概述、示例:遍历节点、示例:插入节点、...

      Java中四种XML解析技术

       SAX 解析器采用了基于事件的模型,它在解析 XML 文档的时候可以触发一系列的事件,当发现给定的tag的时候,它可以激活一个回调方法,告诉该方法制定的标签已经找到。SAX 对内存的要求通常会比较低,因为它让开发...

      dom.sax.pull解析

      Java解析XML的三种方式 Ø Android中,解析Xml数据的三种方式: Ø 1、DOM(org.w3c.dom) Ø “文档对象模型”方式,解析完的Xml将生成一个树状结构的对象。 Ø 2、SAX(org.xml.sax) Ø SimpleAPI for XML,以事件的...

    Global site tag (gtag.js) - Google Analytics