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

来源:互联网 发布:越南人 知乎 编辑:程序博客网 时间:2024/06/05 05:00

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("-----------------");                }            }        }    }}
原创粉丝点击