前言:
XML解析工具
DOM解析原理:
1)JAXP (oracle-Sun公司官方)
2)JDOM工具(非官方)
3)Dom4J工具(非官方)
三大架構(預設讀取xml的工具就是Dom4j)
.......
SAX解析原理:
1)Sax解析工具(oracle-sun公司官方)
老樣子,三個問題:
SAX解析是什麼?
SAX怎麼用?
SAX運用場景?
SAX是什麼?
也是用來解析XML的
SAX解析工具- 内置在jdk中。org.xml.sax.*
SAX運用場景?
DOM解析原理:一次性把xml文檔加載進記憶體,然後在記憶體中建構Document樹。
對記憶體要求比較要。
缺點: 不适合讀取大容量的xml檔案,容易導緻記憶體溢出。
SAX解析原理: 加載一點,讀取一點,處理一點。對記憶體要求比較低。
SAX解析工具核心:
核心的API:
SAXParser類: 用于讀取和解析xml檔案對象
parse(File f, DefaultHandler dh)方法: 解析xml檔案
參數一: File:表示 讀取的xml檔案。
參數二: DefaultHandler: SAX事件處理程式。使用DefaultHandler的子類
第一步:建立對象
//1.建立SAXParser對象
SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
//2.調用parse方法
/**
* 參數一: xml文檔
* 參數二: DefaultHandler的子類 MyDefaultHandler()為自定義
*/
parser.parse(new File(".\\src\\Go\\person.xml"),
new MyDefaultHandler());
注意:
這裡建立SAXParser對象 不能直接通過構造函數來創造,因為用到了單例工廠模式。
連結:類 SAXParser的jdk文檔
是以建立一個SAXParser對象 需要:
SAXParserFactory.newInstance().newSAXParser();
DefaultHandler類的API:後三個最重要
- void startDocument() : 在讀到文檔開始時調用
- void endDocument() :在讀到文檔結束時調用
-
void startElement(String uri, String localName, String qName, Attributes attributes) :
讀到開始标簽時調用
- void endElement(String uri, String localName, String qName) :讀到結束标簽時調用
- void characters(char[] ch, int start, int length) : 讀到文本内容時調用
第二步:自定義類繼承DefaultHandler重寫方法
這些都是要重寫的 舉個例子:
public class MyDefaultHandler extends DefaultHandler {
/**
* 開始文檔時調用
*/
@Override
public void startDocument() throws SAXException {
System.out.println("MyDefaultHandler.startDocument()");
}
/**
* 開始标簽時調用
* @param qName: 表示開始标簽的标簽名
* @param attributes: 表示開始标簽内包含的屬性清單
*/
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
System.out.println("MyDefaultHandler.startElement()-->"+qName);
}
/**
* 結束标簽時調用
* @param qName: 結束标簽的标簽名稱
*/
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
System.out.println("MyDefaultHandler.endElement()-->"+qName);
}
/**
* 讀到文本内容的時調用
* @param ch: 表示目前讀完的所有文本内容
* @param start: 表示目前文本内容的開始位置
* @param length: 表示目前文本内容的長度
* char[]( 張三 20) 100
* 98 2
*/
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
//得到目前文本内容
String content = new String(ch,start,length);
System.out.println("MyDefaultHandler.characters()-->"+content);
}
/**
* 結束文檔時調用
*/
@Override
public void endDocument() throws SAXException {
System.out.println("MyDefaultHandler.endDocument()");
}
}
xml樣例:
<?xml version="1.0" encoding="utf-8"?>
<contactList>
<contact id="001" name="eric">
<name>張三</name>
<age>20</age>
<phone>134222223333</phone>
<email>[email protected]</email>
<qq>432221111</qq>
</contact>
<contact id="002" name="jacky">
<name>eric</name>
<age>20</age>
<phone>134222225555</phone>
<email>[email protected]</email>
<qq>432222222</qq>
</contact>
</contactList>
結果:
MyDefaultHandler.startDocument()
MyDefaultHandler.startElement()-->contactList
MyDefaultHandler.characters()-->
MyDefaultHandler.startElement()-->contact
MyDefaultHandler.characters()-->
MyDefaultHandler.startElement()-->name
MyDefaultHandler.characters()-->張三
MyDefaultHandler.endElement()-->name
MyDefaultHandler.characters()-->
MyDefaultHandler.startElement()-->age
MyDefaultHandler.characters()-->20
MyDefaultHandler.endElement()-->age
MyDefaultHandler.characters()-->
MyDefaultHandler.startElement()-->phone
MyDefaultHandler.characters()-->134222223333
MyDefaultHandler.endElement()-->phone
MyDefaultHandler.characters()-->
MyDefaultHandler.startElement()-->email
MyDefaultHandler.characters()-->[email protected]
MyDefaultHandler.endElement()-->email
MyDefaultHandler.characters()-->
MyDefaultHandler.startElement()-->qq
MyDefaultHandler.characters()-->432221111
MyDefaultHandler.endElement()-->qq
MyDefaultHandler.characters()-->
MyDefaultHandler.endElement()-->contact
MyDefaultHandler.characters()-->
MyDefaultHandler.startElement()-->contact
MyDefaultHandler.characters()-->
MyDefaultHandler.startElement()-->name
MyDefaultHandler.characters()-->eric
MyDefaultHandler.endElement()-->name
MyDefaultHandler.characters()-->
MyDefaultHandler.startElement()-->age
MyDefaultHandler.characters()-->20
MyDefaultHandler.endElement()-->age
MyDefaultHandler.characters()-->
MyDefaultHandler.startElement()-->phone
MyDefaultHandler.characters()-->134222225555
MyDefaultHandler.endElement()-->phone
MyDefaultHandler.characters()-->
MyDefaultHandler.startElement()-->email
MyDefaultHandler.characters()-->[email protected]
MyDefaultHandler.endElement()-->email
MyDefaultHandler.characters()-->
MyDefaultHandler.startElement()-->qq
MyDefaultHandler.characters()-->432222222
MyDefaultHandler.endElement()-->qq
MyDefaultHandler.characters()-->
MyDefaultHandler.endElement()-->contact
MyDefaultHandler.characters()-->
MyDefaultHandler.endElement()-->contactList
MyDefaultHandler.endDocument()
問題:MyDefaultHandler.characters()-->空白 ?
答:
<contactList>
<contact>
之間也是有文本的 是換行和空格 被characters方法讀取了。
來看一下SAX解析XML的流程圖:(圖檔來自傳智播客)
回到開頭
SAX解析原理: 加載一點,讀取一點,處理一點。對記憶體要求比較低。
總結:
==================DOM解析 vs SAX解析 ============================
DOM解析 :
原理: 一次性加載xml文檔,不适合大容量的檔案讀取
DOM解析可以任意進行增删改成
DOM解析任意讀取任何位置的資料,甚至往回讀
DOM解析面向對象的程式設計方法(Node,Element,Attribute),
Java開發者編碼比較簡單。
SAX解析 :
原理: 加載一點,讀取一點,處理一點。适合大容量檔案的讀取
SAX解析隻能讀取
SAX解析隻能從上往下,按順序讀取,不能往回讀
SAX解析基于事件的程式設計方法。java開發編碼相對複雜。
XML操作:
1)Dom4j修改xml文檔
new XMLWrier();
......
2)xPath技術: 快速查詢xml節點
selectNodes()
selectSinglNode();
3) SAX解析
SAXParser parse
parser()
DefaultHandler類:
startElement();
characters();
endElement();