昨天谈了使用Jaxp采用DOM的方式进行解析XML文件,那么今天来看下SAX方式风采吧!另外还提供一种最常用的解释方法——DOM4j。
1.在使用SAX解析方式之前,必须要明白我们为什么会选用SAX方式来对XML进行解析?
这也正是昨天谈到的SAX和DOM方式之间的优缺点,在使用DOM方式进行解析时往往会因XML文件特别大而导致计算机大量内存消耗,最后导致内存溢出,而SAX方式恰恰弥补了这点,它允许在读取文档时就直接对文档进行处理,而不是像DOM方式那样要等待XML载入内存后才进行操作。
2.如何实现SAX方式对XML进行解析?
主要涉及到两部分:
(1).解析器
在解析某个XML文档时,只要解析到XML文档的一个组成部分,都会调用一个处理器事件;
(2).事件处理器:
这部分主要是由程序员自己来写,通过事件处理器中的方法参数就可以得到SAX解析器解析数据,从而决定如何对数据进行处理。
以下通过一个实例具体看SAX如何实现:
XML示例文件
//book.xml文件
<书架>
<书>
<书名 name="Thinking in Java">Java程序编程思想书名>
<作者>张孝祥作者>
<出厂价>69.0元出厂价>
<售价>109.0元售价>
<售价>209.0元售价>
书>
<书>
<书名 name="CSS禅意花园">CSS禅意花园书名>
<作者>某某作者>
<出厂价>39.0元出厂价>
<售价>45.0元售价>
书>Cecilia
书架>
实体类:book
public class Book {
private String name;
private String author;
private String price;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
第一种事件处理器:ListHandler
/**
* 用于获取全部的标签
* @author 芷若初荨
*
*/
public class ListHandler implements ContentHandler {
@Override
public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
System.out.println("<"+qName+">");
for(int i=0;atts!=null&&i
这种处理器主要是为了实现获取全部的内容,但是需要重写@Override全部的函数。
第二种事件处理器:TagValueHandler
/**
* 获取指定的标签
* @author 芷若初荨
*
*/
public class TagValueHandler extends DefaultHandler {
private String currentTag;
private int needNumber=2;
private int currentNumber;
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes)
throws SAXException {
currentTag=qName;
if(currentTag.equals("作者")){
currentNumber++;
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
currentTag=null;
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
if("作者".equals(currentTag)&¤tNumber==needNumber){
System.out.println(new String(ch, start, length));
}
}
}
这种处理器主要是为了实现获取指定标签内容。
第三种事件处理器:BeanListHandler
/**
* 使用Bean来实现处理器
* @author 芷若初荨
*
*/
class BeanListHandler extends DefaultHandler{
private List list=new ArrayList();
private String currentTag;
private Book book;
@Override
public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException {
currentTag=name;
if("书".equals(currentTag)){
book=new Book();
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
if("书名".equals(currentTag)){
String name=new String(ch, start, length);
book.setName(name);
}
if("作者".equals(currentTag)){
String author=new String(ch, start, length);
book.setAuthor(author);
}
if("售价".equals(currentTag)){
String price=new String(ch, start, length);
book.setPrice(price);
}
}
@Override
public void endElement(String uri, String localName, String name) throws SAXException {
if(name.equals("书")){
list.add(book);
book=null;
}
currentTag=null;
}
public List getBooks(){
return list;
}
}
测试类:main
/**
* 使用Sax解析XML文档
* @author 芷若初荨
*
*/
public class SAXAnalysisXML {
public static void main(String[] args) throws Exception{
SAXParserFactory saxfactory=SAXParserFactory.newInstance();
SAXParser saxp=saxfactory.newSAXParser();
XMLReader reader=saxp.getXMLReader();
BeanListHandler handler=new BeanListHandler();
reader.setContentHandler(handler);
reader.parse("msg/book.xml");
List list=handler.getBooks();
System.out.println(list);
}
}
经过以上的实例,相信应该对SAX的方式有所了解啦,接下来,让我们来看一种最常用的解析方式,那就是DOM4j解析方式。
3.DOM4j解析方式
DOM4j是一个简单灵活的开放源代码的库,是一个非常优秀的Java XML API,具有性能优异、功能强大、极易使用的优点。如Hibernate框架。
那么如何使用DOM4j来对XML文档进行增删改查的操作呢?还是通过一个实例来让大家体会DOM4j给大家解析XML带来的优势。
XML实例文档还是使用上面的book.xml文件
读取第二本书的书名
@Test
public void read() throws Exception{
SAXReader reader=new SAXReader();
Document document=reader.read(new File("msg/book.xml"));
Element root=document.getRootElement();
Element book=(Element) root.elements("书").get(0);
String value=book.element("书名").getText();
System.out.println(value);
}
读取第二本书的书的属性
@Test
public void readAttribute() throws Exception{
SAXReader reader=new SAXReader();
Document document=reader.read(new File("msg/book.xml"));
Element root=document.getRootElement();
Element book=(Element) root.elements("书").get(0);
String value=book.element("书名").attributeValue("name");
}
添加新的售价(广泛地)
@Test
public void Add() throws Exception{
SAXReader reader=new SAXReader();
Document document=reader.read(new File("msg/book.xml"));
Element book=document.getRootElement().element("书");
book.addElement("售价").setText("209.0元");
OutputFormat format=OutputFormat.createPrettyPrint();
format.setEncoding("UTF-8");
XMLWriter writer=new XMLWriter(new FileOutputStream("msg/book.xml"),format);
writer.write(document);
writer.close();
}
在第一本书的指定位置上进行添加新的售价
/ 在第一本书的指定位置上进行添加新的售价
@Test
public void AddPrice() throws Exception{
SAXReader reader=new SAXReader();
Document document=reader.read(new File("msg/book.xml"));
Element book=document.getRootElement().element("书");
List list=book.elements();
Element price=DocumentHelper.createElement("售价");
price.setText("200元");
list.add(2, price);
OutputFormat format=OutputFormat.createPrettyPrint();
format.setEncoding("UTF-8");
XMLWriter writer=new XMLWriter(new FileOutputStream("msg/book.xml"),format);
writer.write(document);
writer.close();
}
删除售价的节点
@Test
public void removeNode() throws Exception{
SAXReader reader=new SAXReader();
Document document=reader.read(new File("msg/book.xml"));
Element price=document.getRootElement().element("书").element("售价");
price.getParent().remove(price);
OutputFormat format=OutputFormat.createPrettyPrint();
format.setEncoding("UTF-8");
XMLWriter writer=new XMLWriter(new FileOutputStream("msg/book.xml"),format);
writer.write(document);
writer.close();
}
更新节点
@Test
public void UpdateNode() throws Exception{
SAXReader reader=new SAXReader();
Document document=reader.read(new File("msg/book.xml"));
Element book=(Element) document.getRootElement().elements("书").get(1);
book.getParent().setText("Cecilia");
OutputFormat format=OutputFormat.createPrettyPrint();
format.setEncoding("UTF-8");
XMLWriter writer=new XMLWriter(new FileOutputStream("msg/book.xml"),format);
writer.write(document);
writer.close();
}