XML文档解析---SAX和StAX解析技术

SAX、STAX和DOM,DOM4J技术一样,都可以用来解析XML文档

SAX:Simple Api for XML


SAX在解析文档时使用的是边读取边解析的方式,而不是一次性的将文档全部装入内存中。
读取速度很快,占用内存少。
仅向前,不能任意的读取一个节点,也不能修改XML文件。

通过事件触发、监听来实现

主要实现:XMLReader 监听,文本解析过程,通过事件来触发行为:(文档开头事件、开始解析元素事件等)
* 基本步骤:
* 一:拿到SAXParser
* 二:通过SAXParser拿到XMLReader
* 三:通过XMLReader 对解析过程进行监听,并且写好触发行为
* 四:通过XMLReader来解析XML文档

StAX

The Streaming API for XML基于流的XML编程接口 StAX即可读文档也可以写文档。而SAX只可以读取文档。
StAX编程接口都位于javax.xml.stream包中。StAX提供了两种方式的编程接口,它们是:
Iterator API它的特点是:方便易用、实现简单。
XMLEventReader和XMLEventWriter。 Crusor API它的特点是:运行速度快,底层编程。
主要类是:XMLStreamReader和XMLStreamWriter

下面通过演示解析一个XML文档为例演示学习SAX和StAX
users.xml文档代码

<?xml version="1.0" encoding="UTF-8"?>
<users> 
  <user id="A001"> 
    <name>Jack</name>  
    <age>22</age> 
  </user>  
  <user id="A002"> 
    <name>张三</name>  
    <age>24</age> 
  </user>  
  <user id="B001"> 
    <name>小李</name>  
    <age>20</age> 
  </user>  
  <user id="B002"> 
    <name>小张</name>  
    <age>28</age> 
  </user>  
  <user id="C001"> 
    <name>刘备</name>  
    <age>35</age> 
  </user>  
  <user id="888">
    <name>湖南城市大学</name>
    <age>15</age>
  </user>
</users>

需求,要求把users.xml中的信息解析并输出如下形式:
id: A001
name: Jack
age: 22
————–
id: A002
name: 张三
age: 24
————-
….

SAX解析及注释代码

package cn.hncu.jaxp.sax;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.junit.Test;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

/**
 * SAX 解析XML文档
 * @author<a href="mailto:953801304@qq.com">胡龙华</a>
 * @version 2017-6-2  下午12:17:19
 * @fileName SaxDemo2.java
 */
public class SaxDemo2 {
    @Test
    public void demo1() throws Exception{
        /**主要实现:XMLReader 监听,文本解析过程,通过事件来触发行为:(文档开头事件、开始解析元素事件等)
         *  基本步骤:
         * 一:拿到SAXParser 
         * 二:通过SAXParser拿到XMLReader
         * 三:通过XMLReader 对解析过程进行监听,并且写好触发行为
         * 四:通过XMLReader来解析XML文档
         */
        /*
           需求,要求把users.xml中的信息解析并输出如下形式:
            id: A001
            name: Jack
            age: 22
            --------------
            id: A002
            name: 张三
            age: 24
            -------------
            .... 
         */
        SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
        XMLReader reader = parser.getXMLReader();
        reader.setContentHandler( new DefaultHandler() {
            boolean isContent = false;
            @Override
            public void characters(char[] ch, int start, int length)
                    throws SAXException {
                String str = new String(ch, start, length);
                if(isContent){
                    System.out.println(str);
                }
            }

            @Override
            public void startDocument() throws SAXException {
                System.out.println("文档解析开始!");
            }

            @Override
            public void endDocument() throws SAXException {
                System.out.println("文档解析结束!");
            }

            @Override
            public void startElement(String uri, String localName,
                    String qName, Attributes attributes) throws SAXException {
                if(qName.equals("user")){
                    System.out.println("id:"+attributes.getValue("id"));
                }else if(qName.equals("name")){
                    isContent = true;
                    System.out.print(qName+":");
                }else if(qName.equals("age")){
                    isContent = true;
                    System.out.print(qName+":");
                }

            }

            @Override
            public void endElement(String uri, String localName, String qName)
                    throws SAXException {
                isContent = false;
                if(qName.equals("user")){
                    System.out.println("-------------");
                }
            }


        });
        System.out.println("------------");
        reader.parse("./xml/users.xml");

    }
}

StAX解析及注释代码

package cn.hncu.jaxp.stax;

import java.io.FileReader;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.events.Characters;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
/**
 * @author<a href="mailto:953801304@qq.com">胡龙华</a>
 * @version 2017-6-2  下午2:23:45
 * @fileName StAXDemo2.java
 */
public class StAXDemo2 {
    /**
     StAX 解析XML文档,是把XML 文档当做流读进来。然后通过迭代器解析

    需求,要求把users.xml中的信息解析并输出如下形式:
        id: A001
        name: Jack
        age: 22
        --------------
        id: A002
        name: 张三
        age: 24
        -------------
        .... 
     */
    public static void main(String[] args) throws Exception{

        XMLInputFactory xif  = XMLInputFactory.newInstance();

        XMLEventReader reader = xif.createXMLEventReader( new FileReader("./xml/users.xml"));

        // reader  类似 Scanner  的sc

        while(reader.hasNext()){
            XMLEvent xe =  reader.nextEvent();
            if(xe.isStartDocument()){
                // 开始解析文档
                System.out.println("开始解析文档");
            }
            if(xe.isStartElement()){
                StartElement se =xe.asStartElement();
                if(se.getName().getLocalPart().equals("user")){
                    String id =se.getAttributeByName(new QName("id")).getValue();
                    System.out.println("id:"+id);
                }else if(se.getName().getLocalPart().equals("name")){
                    //拿文本内容。。
                    Characters c= reader.nextEvent().asCharacters();
                    String name = c.getData();
                    System.out.println("name:"+name);
                }else if(se.getName().getLocalPart().equals("age")){
                    //拿文本内容。。
                    Characters c= reader.nextEvent().asCharacters();
                    String age = c.getData();
                    System.out.println("age:"+age);
                }
            }
            if(xe.isEndElement()){
                EndElement ee = xe.asEndElement();
                if(ee.getName().getLocalPart().equals("user")){
                    System.out.println("----------");
                }
            }
        }
    }
}

下面两个老师的代码

package cn.hncu.jaxp.sax;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.junit.Test;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
public class SaxDemo {

    @Test
    public void demo1() throws Exception{
        //1 获得一个parser
        SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
        //2 获得一个reader(整个解析是围绕这个对象来开展)
        XMLReader reader = parser.getXMLReader();
        //3.1 给reader 设置一个用于解析的监听器※※---我们真正的数据读取在这一步
        reader.setContentHandler( new DefaultHandler(){

            @Override
            public void startDocument() throws SAXException {
                System.out.println("1 开始解析文档....");
            }

            @Override
            public void endDocument() throws SAXException {
                System.out.println("3 文档解析结束....");
            }

            @Override
            public void startElement(String uri, String localName,
                    String qName, Attributes attributes) throws SAXException {
                System.out.println("2.* 一个元素开始....");
            }

            @Override
            public void endElement(String uri, String localName, String qName)
                    throws SAXException {
                System.out.println("2.* 一个元素结束....");
            }

        });

        //3.2 解析动作的触发
        reader.parse("./xml/users.xml");

    }

    /*
       需求,要求把users.xml中的信息解析并输出如下形式:
        id: A001
        name: Jack
        age: 22
        --------------
        id: A002
        name: 张三
        age: 24
        -------------
        .... 
     */

    @Test
    public void demo2() throws Exception{
        //1,2
        SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); //通过工厂new两次
        XMLReader reader = parser.getXMLReader();

        //3.1 解析的监听器
        reader.setContentHandler(new DefaultHandler(){
            private String elementName="";//当前正在解析的元素的名称

            //元素开始时的响应函数
            @Override
            public void startElement(String uri, String localName,
                    String qName, Attributes attributes) throws SAXException {
                if(qName.equals("user")){//qName为当前元素的名字
                    String id= attributes.getValue("id");
                    System.out.println("id: "+id);
                }else if(qName.equals("name") || qName.equals("age")){
                    elementName = qName;
                }
            }

            //元素结束时的响应函数
            @Override
            public void endElement(String uri, String localName, String qName)
                    throws SAXException {
                if(qName.equals("user")){
                    System.out.println("--------------");
                }else if(qName.equals("name") || qName.equals("age")){
                    elementName = "";
                }
            }

            //遇到内容文本(CDATA)时的响应函数
            @Override
            public void characters(char[] ch, int start, int length)
                    throws SAXException {
                //过滤掉“空白符”--文本内容
                if(elementName.equals("")){
                    return;
                }

                String str = new String(ch,start,length);
                System.out.println(elementName+": "+str);
            }

        });

        //3.2 解析动作的触发
        reader.parse("./xml/users.xml");
    }
}
package cn.hncu.jaxp.stax;

import java.io.FileReader;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.events.Characters;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;

public class StAXDemo {
    /*
     * 本例是Stax解析技术演示,需求同SaxDemo.demo2()
    */
    public static void main(String[] args) throws Exception {
    //  XMLInputFactory factory = XMLInputFactory.newFactory();
        XMLInputFactory factory = XMLInputFactory.newInstance();
        XMLEventReader reader = factory.createXMLEventReader(new FileReader("./xml/users.xml"));
        //reader是一个迭代器,类似我们之前一直用的sc ----Scanner把流封装成迭代器
        //reader迭代器中的每一个元素都是一个XMLEvent对象
        while(reader.hasNext()){
            XMLEvent xe = reader.nextEvent(); 
            if(xe.isStartElement()){
                StartElement se = xe.asStartElement();
                if(se.getName().getLocalPart().equals("user")){
                    //读取属性值
                    String id = se.getAttributeByName(new QName("id") ).getValue();
                    System.out.println("id:"+id);
                }else if(se.getName().getLocalPart().equals("name")){
                    //读取文本内容
                    Characters chs = reader.nextEvent().asCharacters(); //文本内容 是 StartElement的下一个事件对象
                    System.out.println("name:"+chs.getData());
                }else if(se.getName().getLocalPart().equals("age")){
                    //读取文本内容
                    Characters chs = reader.nextEvent().asCharacters(); //文本内容 是 StartElement的下一个事件对象
                    System.out.println("age:"+chs.getData());
                }
            }
            if(xe.isEndElement()){
                EndElement ee = xe.asEndElement();
                if(ee.getName().getLocalPart().equals("user")){
                    System.out.println("-----------------");
                }
            }
        }

    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值