Java的Sax解析
我们在学习sax解析之前需要先导入sax的jar包,没有的同学可以到各大网站进行下载哦。
//Bean 类
public class Book {
private String name; //书名
private String author;//作者
private String price;//价格
/**
* @return name
*/
public String getName() {
return name;
}
/**
* @param name 要设置的 name
*/
public void setName(String name) {
this.name = name;
}
/**
* @return author
*/
public String getAuthor() {
return author;
}
/**
* @param author 要设置的 author
*/
public void setAuthor(String author) {
this.author = author;
}
/**
* @return price
*/
public String getPrice() {
return price;
}
/**
* @param price 要设置的 price
*/
public void setPrice(String price) {
this.price = price;
}
/* (非 Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "Book [name=" + name + ", author=" + author + ", price=" + price
+ "]";
}
public Book() {
super();
// TODO 自动生成的构造函数存根
}
public Book(String name, String author, String price) {
super();
this.name = name;
this.author = author;
this.price = price;
}
}
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
//sax解析
public class Sax {
public static void main(String[] args) throws ParserConfigurationException,
SAXException, IOException {
// 1.创建sax解析工厂
SAXParserFactory factory = SAXParserFactory.newInstance();
// 2.调用工厂方法获得解析器
SAXParser parser = factory.newSAXParser();
// 3.获得解析器中的读取器
XMLReader reader = parser.getXMLReader();
// 设置内容处理器
BeanListHandler hander = new BeanListHandler();
reader.setContentHandler(hander);//文本處理器,也是常用的
//reader.setErrorHandler(handler);//錯誤處理器
//reader.setDTDHandler(handler); //DTD處理器
// 读取xml封装对象的内容
reader.parse("src/book.xml");
for (Book book : hander.getList()) {
System.out.println(book);
}
}
// 解析所有标签的处理器
class ListHandler implements ContentHandler {
@Override
public void setDocumentLocator(Locator locator) {
}
@Override
public void startDocument() throws SAXException {
}
@Override
public void endDocument() throws SAXException {
}
@Override
public void startPrefixMapping(String prefix, String uri)
throws SAXException {
}
@Override
public void endPrefixMapping(String prefix) throws SAXException {
}
//读取到xml开始标签,调用该方法。
@Override
public void startElement(String uri, String localName, String qName,// 标签名
Attributes atts// 标签具有的属性集,如果没有则为null
) throws SAXException {
String propetyName = null;
String propetyValue = null;
for (int i = 0; atts != null && i < atts.getLength(); i++) {
propetyName = atts.getQName(i);
propetyValue = atts.getValue(i);
}
System.out.println("<" + qName + " " + propetyName + "=" + propetyValue
+ " >");
}
读到结束标签调用该方法
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
System.out.println("<" + qName + ">");
}
读到文本内容调用该方法(读取标签之间的内容都会调用,包括两个毫不相干标签之间的换行符)
@Override
public void characters(char[] ch,// 读取到的文本内容
int start,// 开始索引
int length// 字符长度
) throws SAXException {
System.out.println(new String(ch, start, length));
}
@Override
public void ignorableWhitespace(char[] ch, int start, int length)
throws SAXException {
}
@Override
public void processingInstruction(String target, String data)
throws SAXException {
}
@Override
public void skippedEntity(String name) throws SAXException {
}
}
//处理器: 获取指定标签名的值
class TagValue extends DefaultHandler {
//因为实现接口,需要实现用不到的方法,所以就继承这个适配器,它里面实现了ContentHandler接口的所有方法,但都是空方法体,你需要用到什么方法就复写哪个方法。不至于非实现用不到的方法。看起来碍眼。
private int count;
/*
* (非 Javadoc)
*
* @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String,
* java.lang.String, java.lang.String, org.xml.sax.Attributes)
*/
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
// TODO 自动生成的方法存根
if ("书".equals(qName)) {
count++;
}
if (count == 2) {
System.out.println("<" + qName + " " + attributes.getQName(0)
+ " = " + attributes.getValue(0) + " >");
}
}
/*
* (非 Javadoc)
*
* @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String,
* java.lang.String, java.lang.String)
*/
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
if (count == 2) {
System.out.println("</ " + qName + " >");
}
}
/*
* (非 Javadoc)
*
* @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int)
*/
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
if (count == 2) {
System.out.println(new String(ch, start, length));
}
}
}
// 将解析的文件封装到对象的处理器
class BeanListHandler extends DefaultHandler {
//任务:将xml中的信息封装到Book对象中。
private String CurrentTag;// 记录最近一次读取到的标签名
private Book book;// xml中的对象
private List<Book> list = new ArrayList<Book>();// 存入book对象的容器
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
CurrentTag = qName;
if ("书".equals(CurrentTag)) {
book = new Book();
}
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
if ("书名".equals(CurrentTag)) {
book.setName(new String(ch, start, length));
}
if ("作者".equals(CurrentTag)) {
book.setAuthor(new String(ch, start, length));
}
if ("价格".equals(CurrentTag)) {
book.setPrice(new String(ch, start, length));
}
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
if ("书".equals(qName)) {
list.add(book);
book = null;
}
CurrentTag = null;// 必须置null,否则NullPointerExcepotion。因为xml空白行也算作文本,也会执行characters方法一次。
// 否则会进入characters方法,用读取的空白行将我们的属性覆盖掉
}
/**
* @return list
*/
public List<Book> getList() {
return list;
}
}
Book的测试XML
<?xml version="1.0" encoding="utf-8" ?>
<书架>
<书><书名>秦皇</书名><作者>君琦</作者><价格>123元</价格></书>
<书><书名>汉武</书名><作者>君琦</作者><价格>123元</价格></书>
<书><书名>唐宗</书名><作者>君琦</作者><价格>123元</价格></书>
<书><书名>宋祖</书名><作者>君琦</作者><价格>123元</价格></书>
</书架>