一、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));
}
}
}