一、sax解析
simple api for xml 社区标准,几乎所有解析器都支持
xml文件->创建sax解析器->事件处理器对xml内容进行处理->读取xml内容
步骤:
1、创建解析工厂;2、创建解析器 ; 3、获取读取器 Xmlreader; 4、对读取器设置内容处理,这里就是要传入指定的事件处理器; 5、完成事件处理,读取xml内容
二、dom与sax解析方法的对比
dom 在解析过程会在内存中建立一个模型,即针对该xml的生成整个dom树的document对象
* 缺点:消耗内存 如果数据过大,产生较大文档消耗内存,容易导致内存溢出
* 优点:增删改方便快速 只要得到dom文档,就可以快速删除、定位等
*
* sax 对xml文件从上往下依次读,读取一行处理一行
* 优点:内存消耗小,解析速度快 允许在读取文档时,不必等到整个文档都装载完才操作
* 缺点:只适合对文档做读取,不适合做增删改
三、示例说明
先写一个简单的xml:
dom1.xml
<?xml version="1.1" encoding="UTF-8" standalone="no"?><书架>
<书>
<书名 name1="XXXXX" name2="******">沉默世界</书名>
<作者>张思宁</作者>
<页数>486</页数>
<售价>38</售价>
</书>
</书架>
<pre class="java" name="code">public class saxDemo1 {
public static void main(String[] args) throws Exception
{
//1、创建解析工厂
SAXParserFactory saxparserfactory = SAXParserFactory.newInstance();
//2、解析器
SAXParser Sparser = saxparserfactory.newSAXParser();
//3、get xmlreader,得到读取器
XMLReader xreader = Sparser.getXMLReader();
//4、设置内容处理器;
//ContentHandler handler = xreader.getContentHandler(); 获取处理器,但处理器的函数都是void类型,返回不了信息,则需要复写内部方法
xreader.setContentHandler(new ListHandler()); //实现ContentHandler,创建对象传入
//5、读取xml文档的内容
xreader.parse(new InputSource("src/cn/itcast/xml/dom1.xml"));
}
}
//写好了一个处理器,得到xml文档所有内容
class ListHandler implements ContentHandler
{
@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 startElement(String uri, String localName, String qName,
Attributes atts) throws SAXException {
// TODO Auto-generated method stub
System.out.println("<"+qName+">"); //当前解析的标签名 标签 qName Attributes 属性
//打印属性
System.out.println("属性个数: "+atts.getLength());
for (int i = 0;i < atts.getLength(); i++)
{
if (atts == null)
{
break;
}
String propName = atts.getLocalName(i); //属性名称
//打印属性名称及对应值
System.out.println("属性"+i+": "+propName+"="+atts.getValue(propName));
}
}
@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
}
}
以上是对sax解析的示例说明,主要是通过实现接口的方法来创建事件处理器;
以下示例通过实现接口、继承类两种方式进行对比:
public class saxDemo2 {
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
//1、创建解析工厂
SAXParserFactory saxparserfactory = SAXParserFactory.newInstance();
//2、解析器
SAXParser Sparser = saxparserfactory.newSAXParser();
//3、get xmlreader,得到读取器
XMLReader xreader = Sparser.getXMLReader();
//4、设置内容处理器;
//ContentHandler handler = xreader.getContentHandler(); 获取处理器,但处理器的函数都是void类型,返回不了信息,则需要复写内部方法
//(1)实现接口 ContentHandler
//xreader.setContentHandler(new ListHandler1()); //实现ContentHandler,创建对象传入
//(2)继承类 DefaultHandler
xreader.setContentHandler(new ListHandler2());
//5、读取xml文档的内容
xreader.parse(new InputSource("src/cn/itcast/xml/dom1.xml"));
}
}
//(1)写好了一个处理器,得到xml文档所有内容
class ListHandler1 implements ContentHandler
{
private String currentTag;
@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 startElement(String uri, String localName, String qName,
Attributes atts) throws SAXException {
currentTag = qName;
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
currentElement = null; //置空方便下个标签的读取
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
// TODO Auto-generated method stub
//解析获得标签的内容
if (currentTag.equals("售价"))
{
System.out.println(currentTag);
System.out.println("售价是:"+new String(ch,start,length)+"len="+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
}
}
//(2)继承类,复写3个方法即可
class ListHandler2 extends DefaultHandler
{
private String currentElement;
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
currentElement = qName;
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
if ("作者".equals(currentElement))
{
System.out.println(new String(ch,start,length));
}
}
}