java-SAX解析XML示例

JAVA 解析 XML 通常有两种方式:DOM 和SAX。DOM(文档对象模型)是W3C标准,提供了标准的解析方式,但其解析效率一直不尽如人意,这是因为DOM解析XML文档时,把所有内容一次性的装载入内存,并构建一个驻留在内存中的树状结构(节点数)。如果需要解析的XML文档过大,或者我们只对该文档中的一部分感兴趣,这样就会引起性能问题。
SAX(simple API for XML)是一种XML解析的替代方法。相比于DOM,SAX是一种速度更快,更有效的方法。它逐行扫描文档,一边扫描一边解析。而且相比于DOM,SAX可以在解析文档的任意时刻停止解析,但任何事物都有其相反的一面,对于SAX来说就是操作复杂。

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

package cd.itcast.day3;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

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.helpers.DefaultHandler;

public class SaxParserDemo {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
saxParse();
}

public static void saxParse() {
// 得到SAX解析工厂实例
SAXParserFactory spf = SAXParserFactory.newInstance();
try {
// 得到SAX解析器
SAXParser sp = spf.newSAXParser();
// 得到XML读取器
// XMLReader xr = sp.getXMLReader();
// 设置XML内容处理器
// xr.setContentHandler(new MyContentHandler());
// xr.parse("D:\\Java\\WorkSpace\\JavaDemo\\src\\cd\\itcast\\day3\\student.xml");

List<Student> list = new ArrayList<Student>();

//直接采用SAX解析器的解析方法,传入一个DefaultHandler实例
sp.parse(
"D:\\Java\\WorkSpace\\JavaDemo\\src\\cd\\itcast\\day3\\student.xml",
new MyDefaultHander(list));

for (Student stu : list) {
System.out.println(stu);
}
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}

//DefaultHandler实现了ContentHandler的方法,因此可以声明一个类继承DefaultHandler,并覆盖我们需要的方法即可.
static class MyDefaultHander extends DefaultHandler {
// 通过够咱函数传递给内部的List,接收解析出来的Student内容.
private List<Student> stuList = null;

// 定义一个标记,获取元素的标签名,根据标签名称做不同的处理.
private String tagName = null;
//Student实例,每解析出一个student元素,将解析出来的内容设置到stu对象,并添加到list中.
private Student stu = null;

public MyDefaultHander(List<Student> stuList) {
this.stuList = stuList;
}

@Override
public void startDocument() throws SAXException {
// TODO Auto-generated method stub
System.out.println("文档开始");
}

@Override
public void endDocument() throws SAXException {
// TODO Auto-generated method stub
System.out.println("文档结束");
}

@Override
public void startElement(String uri, String localName, String qName,
Attributes atts) throws SAXException {
// TODO Auto-generated method stub
// System.out.println("元素开始:" + qName);
tagName = qName; // 元素一开始,记录标记
if ("student".equals(qName)){
stu = new Student();
stu.setId(Integer.parseInt(atts.getValue("id")));
}
}

@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
// TODO Auto-generated method stub
// System.out.println("元素结束:" + qName);
tagName = null; // 清空标记
if ("student".equals(qName)){
stuList.add(stu);
}
}

@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));
if ("name".equals(tagName)) {
stu.setName(new String(ch, start, length));
}
else if ("sex".equals(tagName)) {
stu.setSex(new String(ch, start, length));
}
else if ("age".equals(tagName)) {
stu.setAge(Integer.parseInt(new String(ch, start, length)));
}
}
}

//采用XMLReader必须要覆盖ContentHandler的方法,不方便.
static class MyContentHandler implements ContentHandler {
@Override
public void setDocumentLocator(Locator locator) {
// TODO Auto-generated method stub

}

@Override
public void startDocument() throws SAXException {
// TODO Auto-generated method stub
System.out.println("文档开始");
}

@Override
public void endDocument() throws SAXException {
// TODO Auto-generated method stub
System.out.println("文档结束");
}

@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 startElement(String uri, String localName, String qName,
Attributes atts) throws SAXException {
// TODO Auto-generated method stub
System.out.println("元素开始:" + qName);
}

@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
// TODO Auto-generated method stub
System.out.println("元素结束:" + qName);
}

@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 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

}
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值