Web---XML---⑤Java解析XML---SAX和StAX(官方---第二方)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_34928644/article/details/82048436

SAX解析

Simple Api for XML

SAX在解析文档时使用的是边读取边解析的方式,而不是一次性的将文档全部装入内存中。

所以它的读取速度很快,占用很少的内存。

仅向前,不能任意的读取一个节点。

也不能修改XML文件。

SAX读取一个XML文档的过程:

SAX解析器:

SAXParserFactory

定义工厂 API,使应用程序能够配置和获取基于 SAX 的解析器以解析 XML 文档。

SAXParserSAX解析器。

定义包装 XMLReader 实现类的 API 。此类的实例可以从 SAXParserFactory.newSAXParser() 方法获得。

XMLReader-用于读取XML数据。

通过SAXParser. getXMLReader()获得。

parse(String fileName)用于读取一个XML文档。

代码演示:

准备xml文件(位置:项目根目录下创建一个xml目录,再创建一个users.xml文件,把内容复制进去)

<?xml version="1.0" encoding="UTF-8"?>
<users>
	<user id="A001">
		<name>Jack</name>
		<age>24</age>
	</user>
	<user id="A002">
		<name>张三</name>
		<age>22</age>
	</user>
	<user id="A003">
		<name>李四</name>
		<age>33</age>
	</user>
	<user id="A004">
		<name>Rose</name>
		<age>120</age>
	</user>
	<user id="B001">
		<name>Mike</name>
		<age>18</age>
	</user>
	<user id="S007">
		<name>OKOK</name>
		<age>111</age>
	</user>
	
	
</users>

Java代码

package cn.hncu.sax;

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

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

public class SaxDemo {
	
	@Test
	public void hello() throws Exception{
		/*技术要点:
		  1)用javax.xml.parsers包中的类去获取一个"XML阅读器"org.xml.sax.XMLReader
		  2)用这个"XML阅读器"去解析我们的XML文档---因为是只读,所以解析就是阅读
		  3)※以给阅读器添加监听者的方式来设置具体的解析方案---该方案由"监听者"来决定
		  
       */
		SAXParser sax = SAXParserFactory.newInstance().newSAXParser();
		XMLReader reader = sax.getXMLReader();
		
		///////////我们以后解析时真正需要写的就是下面这一小段有技术含量,其它都可以照搬////////////////
		//※给reader注册(添加)一个监听者,由监听者来设置解析方案
		reader.setContentHandler(new DefaultHandler(){

			@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 {
				System.out.println("一个元素开始,名字为:"+qName);
			}

			@Override
			public void endElement(String uri, String localName, String qName)
					throws SAXException {
				System.out.println("一个元素结束,名字为:"+qName);
			}
			
		});
		
		
		//解析动作的触发
		reader.parse("./xml/users.xml");
		
	}
	
	@Test
	public void getInfoDemo() throws Exception{
		SAXParserFactory factory = SAXParserFactory.newInstance();
		SAXParser parser = factory.newSAXParser();
		XMLReader reader = parser.getXMLReader();
		
		////////设置解析方式///////////
		ContentHandler handler = new DefaultHandler(){
			private String elementName="";
			
			@Override //遇到元素开始时执行这个事件处理方法
			public void startElement(String uri, String localName,
					String qName, Attributes attributes) throws SAXException {
				if("user".equals(qName)){
					String id = attributes.getValue("id");
					System.out.println("id:"+id);
				}else if("name".equals(qName) || "age".equals(qName)){
					elementName=qName;
				}
			}

			@Override
			public void endElement(String uri, String localName, String qName)
					throws SAXException {
				if("name".equals(qName) || "age".equals(qName)){
					elementName="";
				}else if("user".equals(qName)){
					System.out.println("-----------------");
				}
			}

			@Override //遇到文本内容节点时执行
			public void characters(char[] ch, int start, int length)
					throws SAXException {
				if(!"".equals(elementName)){
					System.out.println(elementName+":"+new String(ch,start,length));
				}
			}
			
		};
		reader.setContentHandler(handler);
		
		reader.parse("./xml/users.xml");
	}
	
}

StAX解析

The Streaming API for XML基于流的XML编程接口

扫描二维码关注公众号,回复: 2916444 查看本文章

StAX即可读文档也可以写文档。而SAX只可以读取文档。

StAXAPI编程接口

StAX编程接口都位于javax.xml.stream包中。StAX提供了两种方式的编程接口,它们是:

Iterator API

它的特点是:方便易用、实现简单。

主要类是:XMLEventReaderXMLEventWriter

Crusor API

它的特点是:运行速度快,底层编程。

主要类是:XMLStreamReaderXMLStreamWriter

Iterator API编程接口

XMLEvent

提供一系列的属性方法,判断文件是开始、结束。

StartDocument文档的开始

StartElementEndElement(元素的开始与结束)、Characters(字符串节点元素)

EntityReference 实体引用

Comment注释、EndDocument文档结束,DTD约束

Attribute属性,Namespace命名空间

XMLEventReader

提供遍历XML文档的能力。它的源代码如下:

public interface XMLEventReader extends Iterator {

可见,它就是一个遍历器。

XMLEventWriter

XMLEventWriter提供向写XML的功能。

StAX的工厂类

XMLInputFactoryXMLOutputFactoryXMLEventFactoryStAX的工厂类,通过这些类可以获取readerwriterevent的实例。

代码演示:

准备XML同上面SAX演示的XML

Java代码:

package cn.hncu.stax;

import java.io.FileInputStream;

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;

import org.junit.Test;

public class StAXDemo {
	
	@Test
	public void readDemo() throws Exception{
		//先获得一个StAX阅读器
		XMLInputFactory factory = XMLInputFactory.newFactory();
		XMLEventReader reader = factory.createXMLEventReader(new FileInputStream("./xml/users.xml"));
		
		while(reader.hasNext()){
			XMLEvent ev = reader.nextEvent();
			
			if(ev.isStartElement()){
				StartElement se = ev.asStartElement(); //强转成"StartElement",以便于调用该类中的方法---定义了一些元素开始时可以做的动作
				if( se.getName().getLocalPart().equals("user") ){ //<user>的开始标记
					//属性是开始标签中的,因此这里的id属性直接从se中获取
					String id = se.getAttributeByName( new QName("id") ).getValue();
					System.out.println("id:"+id);
				}else if( se.getName().getLocalPart().equals("name") ){ //<name>的开始标记
					//"文本内容"不属于"开始标签本身",而是它的孩子,因此"文本内容"是"开始标签"的下一个事件对象
					XMLEvent evv = reader.nextEvent();
					//因为我们知道evv就是文本内容,所以可以直接强转,以便于调用Characters类中的一些方法
					Characters chs = evv.asCharacters();
					System.out.println("name:"+chs);
				}else if( se.getName().getLocalPart().equals("age") ){ //<age>的开始标记
					Characters chs =reader.nextEvent().asCharacters();
					System.out.println("age:"+chs);
				}
			} else if(ev.isEndElement()){
				EndElement ee = ev.asEndElement();
				if(ee.getName().getLocalPart().equals("user")){
					System.out.println("----------------");
				}
			}
		}
	}
	
}

 

 

猜你喜欢

转载自blog.csdn.net/qq_34928644/article/details/82048436
今日推荐