Java 使用SAX解析XML文档
DOM,即Document Object Model,中文叫文档对象模型。DOM是W3C定义的标准文档对象模型,是一个与操作系统和编程语言无关的、用于内存存储和操作层次化文档的模型。当按 照DOM模型解析XML文档时,就会在内存中构造一个对应的DOM树,它可以用于不同节点之间的遍历。然而,在遍历之前必须先完成DOM树的构造。因此, 在处理规模较大的XML文档时就很耗内存,占用资源较多。尤其是只需要操作文档中一小部分时效率很低。
SAX,即Simple API for XML的简称,中文叫XML简单应用程序接口。它是一个事实上的标准。与DOM不同的是,它是用事件驱动模型。解析XMl文档时每遇到一个开始或者结束标 签、或者属性、或者一条指令时,程序就产生一个事件来进行相应的处理。所以在操作文档之前不需要对整个文档进行解析。实际上,文档的各个部分可以在进行解 析的同时进行操作。因此,SAX相对于DOM来说更适合操作大文档。
下面介绍一下SAX解析XML文档的方法:
1.通过SAXParserFactory的静态newInstance()方法获取SAXParserFactory实例
SAXParserFactory factory = SAXParserFactory.newInstance();
2.通过SAXPareserFactory实例的newSAXParser()方法返回SAXParser实例
SAXParser parser = factory.newSAXParser();
3.创建一个类继承DefaultHandler,重写其中的一些方法来处理业务,并创建这个类的实例
4.调用parse()方法进行解析
File f = new File("book.xml");
parser.parse(f, sdh);
下面还是直接上例子吧。
xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<bookstore>
<book id="1">
<name>111</name>
<author>222</author>
</book>
<book id="2">
<name>333</name>
<author>444</author>
</book>
</bookstore>
具体实现
SAXxml.java
package com.lpp.test;
import java.io.File;
import java.io.IOException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.SAXException;
import com.lpp.handler.SAXHeadler;
public class SAXxml
{
public static void main(String[] args)
{
// TODO Auto-generated method stub
SAXParserFactory factory = SAXParserFactory.newInstance();
try
{
SAXParser parser = factory.newSAXParser();
SAXHeadler sdh=new SAXHeadler();
File f = new File("book.xml");
parser.parse(f, sdh);
} catch (ParserConfigurationException | SAXException | IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
SAXHandler.java
package com.lpp.handler;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class SAXHeadler extends DefaultHandler
{
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
{
// TODO Auto-generated method stub
super.startElement(uri, localName, qName, attributes);
System.out.println("开始解析"+qName);
if(qName.equals("book"))
{
String value = attributes.getValue("id");
System.out.println("id:"+value);
System.out.println();
}
else if(qName.equals("bookstore"))
{
System.out.println();
}
else if(!qName.equals("book")&&!qName.equals("bookstore"))
{
System.out.println("节点名:"+qName);
}
// System.out.println();
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException
{
// TODO Auto-generated method stub
super.endElement(uri, localName, qName);
System.out.println("结束解析"+qName);
System.out.println();
}
@Override
public void startDocument() throws SAXException
{
// TODO Auto-generated method stub
super.startDocument();
System.out.println("开始解析xml文档");
System.out.println();
}
@Override
public void endDocument() throws SAXException
{
// TODO Auto-generated method stub
super.endDocument();
System.out.println("结束解析xml文档");
System.out.println();
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException
{
// TODO Auto-generated method stub
super.characters(ch, start, length);
String chs=new String(ch, start, length);
if(!chs.trim().equals(""))
{
System.out.println("节点值:"+chs);
}
}
}
注意
xml文档中会有空白的节点值,所以在重写characters()方法时,加上了判断条件。String chs=new String(ch, start, length); if(!chs.trim().equals("")),
判断节点值不为空时才进行输出操作。