SAX official website SAX API 下載連結
在Sax的解析過程中,讀取到文檔開頭、結尾,元素的開頭和結尾都會觸發一些回調方法,你可以在這些回調方法中進行相應事件處理
這四個方法是:startDocument() 、 endDocument()、 startElement()、 endElement。此外,讀取到節點處是不夠的,我們還需要characters()方法來仔細處理元素內包含的內容,將這些回調方法集合起來,便形成了一個類,這個類也就是我們需要的觸發器。
一般從Main方法中讀取文檔,卻在觸發器中處理文檔,這就是所謂的事件驅動解析方法。
如上圖,在觸發器中,首先開始讀取文檔,然後開始逐個解析元素,每個元素中的內容會返回到characters()方法,接著結束元素讀取,所有元素讀取完後,結束文檔解析。
現在我們開始創建觸發器這個類,要創建這個類首先需要繼承DefaultHandler
創建SaxHandler,並覆寫相應方法:
import
org.xml.sax.Attributes;
import
org.xml.sax.SAXException;
import
org.xml.sax.helpers.DefaultHandler;
public
class
SaxHandler
extends
DefaultHandler {
/* 此方法有三个参数
arg0是传回来的字符数组,其包含元素内容
arg1和arg2分别是数组的开始位置和结束位置 */
@Override
public
void
characters(
char
[] arg0,
int
arg1,
int
arg2)
throws
SAXException {
String content =
new
String(arg0, arg1, arg2);
System.out.println(content);
super
.characters(arg0, arg1, arg2);
}
@Override
public
void
endDocument()
throws
SAXException {
System.out.println(
"\n…………结束解析文档…………"
);
super
.endDocument();
}
/* arg0是名称空间
arg1是包含名称空间的标签,如果没有名称空间,则为空
arg2是不包含名称空间的标签 */
@Override
public
void
endElement(String arg0, String arg1, String arg2)
throws
SAXException {
System.out.println(
"结束解析元素 "
+ arg2);
super
.endElement(arg0, arg1, arg2);
}
@Override
public
void
startDocument()
throws
SAXException {
System.out.println(
"…………开始解析文档…………\n"
);
super
.startDocument();
}
/*arg0是名称空间
arg1是包含名称空间的标签,如果没有名称空间,则为空
arg2是不包含名称空间的标签
arg3很明显是属性的集合 */
@Override
public
void
startElement(String arg0, String arg1, String arg2,
Attributes arg3)
throws
SAXException {
System.out.println(
"开始解析元素 "
+ arg2);
if
(arg3 !=
null
) {
for
(
int
i =
0
; i < arg3.getLength(); i++) {
// getQName()是获取属性名称,
System.out.print(arg3.getQName(i) +
"=\""
+ arg3.getValue(i) +
"\""
);
}
}
System.out.print(arg2 +
":"
);
super
.startElement(arg0, arg1, arg2, arg3);
}
}
XML文档:
<? xml version="1.0" encoding="UTF-8"?> < books > < book id="001"> < title >Harry Potter</ title > < author >J K. Rowling</ author > </ book > < book id="002"> < title >Learning XML</ title > < author >Erik T. Ray</ author > </ book > </ books > |
TestDemo测试类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| import java.io.File; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; public class TestDemo { public static void main(String[] args) throws Exception { // 1.实例化SAXParserFactory对象 SAXParserFactory factory = SAXParserFactory.newInstance(); // 2.创建解析器 SAXParser parser = factory.newSAXParser(); // 3.获取需要解析的文档,生成解析器,最后解析文档 File f = new File( "books.xml" ); SaxHandler dh = new SaxHandler(); parser.parse(f, dh); } } |
输出结果:
…………开始解析文档………… 开始解析元素 books books: 开始解析元素 book id="001"book: 开始解析元素 title title:Harry Potter 结束解析元素 title 开始解析元素 author author:J K. Rowling 结束解析元素 author 结束解析元素 book 开始解析元素 book id="002"book: 开始解析元素 title title:Learning XML 结束解析元素 title 开始解析元素 author author:Erik T. Ray 结束解析元素 author 结束解析元素 book 结束解析元素 books …………结束解析文档…………
|
上面的虽然正确显示了执行流程,但是输出却很乱
为了更加清晰的执行此流程,我们还可以重写SaxHandler,使其将原先的xml文档还原一遍
重写的SaxHandler类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
| import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; public class SaxHandler extends DefaultHandler { @Override public void characters( char [] arg0, int arg1, int arg2) throws SAXException { System.out.print( new String(arg0, arg1, arg2)); super .characters(arg0, arg1, arg2); } @Override public void endDocument() throws SAXException { System.out.println( "\n结束解析" ); super .endDocument(); } @Override public void endElement(String arg0, String arg1, String arg2) throws SAXException { System.out.print( "</" ); System.out.print(arg2); System.out.print( ">" ); super .endElement(arg0, arg1, arg2); } @Override public void startDocument() throws SAXException { System.out.println( "开始解析" ); String s = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" ; System.out.println(s); super .startDocument(); } @Override public void startElement(String arg0, String arg1, String arg2, Attributes arg3) throws SAXException { System.out.print( "<" ); System.out.print(arg2); if (arg3 != null ) { for ( int i = 0 ; i < arg3.getLength(); i++) { System.out.print( " " + arg3.getQName(i) + "=\"" + arg3.getValue(i) + "\"" ); } } System.out.print( ">" ); super .startElement(arg0, arg1, arg2, arg3); } } |
执行结果:

From: 使用SAX解析 , 清新下午茶 , developerWorkers