javaWeb-day02(用Jaxp做sax解析)

本文介绍了JavaWeb中使用JAXP的SAX解析XML文档的方式,对比了DOM解析的优缺点。详细阐述了SAX解析过程,包括通过SAXParserFactory创建解析器,设置ContentHandler,解析XML文件的步骤。并提供了书架类XML文件的示例,展示了如何获取节点值。建议使用DefaultHandler作为事件处理器的基础,以简化代码编写。
摘要由CSDN通过智能技术生成

Dom 和 Sax 的区别:   

  1. 在使用 DOM 解析 XML 文档时,需要读取整个 XML 文档,在内存中构架代表整个 DOM 树的Doucment对象,从而再对XML文档进行操作。此种情况下,如果 XML 文档特别大,就会消耗计算机的大量内存,并且容易导致内存溢出。
  2. SAX解析允许在读取文档的时候,即对文档进行处理,而不必等到整个文档装载完才会文档进行操作。

SAX采用事件处理的方式解析XML文件,利用SAX 解析XML 文档,涉及两个部分:解析器和事件处理器:
  • 解析器可以使用JAXP的API创建,创建出SAX解析器后,就可以指定解析器去解析某个XML文档。
  • 解析器采用SAX方式在解析某个XML文档时,它只要解析到XML文档的一个组成部分,都会去调用事件处理器的一个方法,解析器在调用事件处理器的方法时,会把当前解析到的xml文件内容作为方法的参数传递给事件处理器。
  • 事件处理器由程序员编写,程序员通过事件处理器中方法的参数,就可以很轻松地得到sax解析器解析到的数据,从而可以决定如何对数据进行处理。



阅读ContentHandler API文档,常用方法:startElement、endElement、characters

org.xml.sax 
接口 ContentHandler

public interface ContentHandler

方法摘要
 voidcharacters(char[] ch, int start, int length) 
          接收字符数据的通知。
 voidendDocument() 
          接收文档的结尾的通知。
 voidendElement(String uri, String localName, String qName) 
          接收元素结束的通知。
 voidendPrefixMapping(String prefix) 
          结束前缀 URI 范围的映射。
 voidignorableWhitespace(char[] ch, int start, int length) 
          接收元素内容中可忽略的空白的通知。
 voidprocessingInstruction(String target, String data) 
          接收处理指令的通知。
 voidsetDocumentLocator(Locator locator) 
          接收用来查找 SAX 文档事件起源的对象。
 voidskippedEntity(String name) 
          接收跳过的实体的通知。
 voidstartDocument() 
          接收文档的开始的通知。
 voidstartElement(String uri, String localName, String qName, Attributes atts) 
          接收元素开始的通知。
 voidstartPrefixMapping(String prefix, String uri) 
          开始前缀 URI 名称空间范围映射。



SAX方式解析XML文档:

1.使用SAXParserFactory创建SAX解析工厂
    SAXParserFactory spf = SAXParserFactory.newInstance();
2.通过SAX解析工厂得到解析器对象
    SAXParser sp = spf.newSAXParser();
3.通过解析器对象得到一个XML的读取器
    XMLReader xmlReader = sp.getXMLReader();
4.设置读取器的事件处理器
    xmlReader.setContentHandler(new BookParserHandler());
5.解析xml文件
    xmlReader.parse("book.xml");



新建一个工程之后,可以选住这个项目,右键 将其他项目都关闭( close unrelated projects )




org.xml.sax 
接口 Attributes

public interface Attributes

方法摘要
 intgetIndex(String qName) 
          通过 XML 限定(前缀)名查找属性的索引。
 intgetIndex(String uri, String localName) 
          通过名称空间的名称查找属性的索引。
 intgetLength() 
          返回此列表中的属性个数
 StringgetLocalName(int index) 
          通过索引查找属性的本地名称。
 StringgetQName(int index) 
          通过索引查找属性的 XML 限定(前缀)
 StringgetType(int index) 
          通过索引查找属性的类型。
 StringgetType(String qName) 
          通过 XML 限定(前缀)名查找属性的类型。
 StringgetType(String uri, String localName) 
          根据名称空间的名称查找属性的类型。
 StringgetURI(int index) 
          通过索引查找属性的名称空间 URI。
 StringgetValue(int index) 
          通过索引查找属性的值
 StringgetValue(String qName) 
          通过 XML 限定(前缀)名查找属性的值。
 StringgetValue(String uri, String localName) 
          根据名称空间的名称查找属性的值。


book.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>

<书架>
	<书 name="yyyyy">
		<售价>109元</售价>
		<售价>39元</售价>
		<书名>Java就业培训教程</书名>
		<作者>张孝祥</作者>
	    
	</书>
	<书>
		<书名>JavaScript网页开发</书名>
		<作者>张孝祥</作者>
		<售价>28.00元</售价>
	</书>
</书架>

演示:打印读到的XML的内容

package cn.itcast.sax;

import java.io.IOException;

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

import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

public class Demo1 {

	/**
	 * Sax方式解析book.xml文件
	 * @throws SAXException 
	 * @throws ParserConfigurationException 
	 * @throws IOException 
	 * */
	public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
		//1.得到工厂
		SAXParserFactory factory = SAXParserFactory.newInstance();
		
		//2.使用工厂得到解析器
		SAXParser parser = factory.newSAXParser();
		
		//3.使用解析器得到读取器
		XMLReader reader = parser.getXMLReader();
		
		//4.在读之前设置好事件处理器
		reader.setContentHandler(new MyContentHandler());
		
		//5.读取XML文档
		reader.parse("src/book.xml");
		
	}

}

class MyContentHandler implements ContentHandler{

	@Override
	public void startElement(String uri, String localName, String qName,
			Attributes atts) throws SAXException {
		// TODO Auto-generated method stub
		System.out.print("<");
		System.out.print(qName);
		for(int x=0; x<atts.getLength(); x++){
			System.out.print(" "+atts.getQName(x)+"=\""+atts.getValue(x)+"\"");
		}
		System.out.println(">");
		
	}

	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		// TODO Auto-generated method stub
		System.out.print("</");
		System.out.print(qName);
		System.out.println(">");
	}
	
	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		// TODO Auto-generated method stub
		System.out.println(new String(ch,start,length));
	}
	
	@Override
	public void setDocumentLocator(Locator locator) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void startDocument() throws SAXException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void endDocument() throws SAXException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void startPrefixMapping(String prefix, String uri)
			throws SAXException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void endPrefixMapping(String prefix) throws SAXException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void ignorableWhitespace(char[] ch, int start, int length)
			throws SAXException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void processingInstruction(String target, String data)
			throws SAXException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void skippedEntity(String name) throws SAXException {
		// TODO Auto-generated method stub
		
	}
	
}


运行结果:

<书架>

<书 name="yyyyy">

<售价>

109元

</售价>

<售价>

39元

</售价>

<书名>

Java就业培训教程

</书名>

<作者>

张孝祥

</作者>

</书>

<书>

<书名>

JavaScript网页开发

</书名>

<作者>

张孝祥

</作者>

<售价>

28.00元

</售价>

</书>


</书架>




需求:获取某个节点的值

ContentHandler 的已知实现类:

这样每次写事件处理器的时候就可以来实现 DefaultHandler,免的每次都实现那么多没用的方法。

org.xml.sax.helpers 
DefaultHandler

public class DefaultHandler
extends Object
implements EntityResolver, DTDHandler, ContentHandler, ErrorHandler


你写一个自己的事件处理器,继承DefaultHandler类,覆盖你想覆盖的方法就行了。






package cn.itcast.sax;

import java.io.IOException;

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

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

public class Demo1 {

	/**
	 * Sax方式解析book.xml文件
	 * @throws SAXException 
	 * @throws ParserConfigurationException 
	 * @throws IOException 
	 * */
	public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
		//1.得到工厂
		SAXParserFactory factory = SAXParserFactory.newInstance();
		
		//2.使用工厂得到解析器
		SAXParser parser = factory.newSAXParser();
		
		//3.使用解析器得到读取器
		XMLReader reader = parser.getXMLReader();
		
		//4.在读之前设置好事件处理器
		reader.setContentHandler(new MyContentHandler2());
		
		//5.读取XML文档
		reader.parse("src/book.xml");
		
	}

}

//获取第一个售价节点的值:<售价>109元</售价>
class MyContentHandler2 extends DefaultHandler{

	private Boolean flag = false;
	private int index = 1;
	
	@Override
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {
		if(qName.equals("售价")){
			flag = true;
		}
	}

	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		if(qName.equals("售价")){
			flag = false;
			index--;
		}
	}

	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		if(flag == true && index==1){
			System.out.println(new String(ch,start,length));
		}
	}
	
}


运行结果:

109元




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值