您的位置:首页 > 其它

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

2017-06-02 14:32 197 查看
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("-----------------");
}
}
}

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  xml api 文档 内存 SAX-STAX