本文使用SAX来解析XML,在Android里面可以使用SAX和DOM两种方法来解析XML,DOM方法需要把整个XML文件读入内存再解析,比较消耗内存,而SAX基于事件驱动的处理方式,可以在各节点触发回调函数,不过SAX适合节点结构简单的XML文档,复杂的XML文档在后期的节点深度处理会有点麻烦。
本文要解析的test.xml文件如下:
1
2
3
4
5
6
7
8
|
<? xml version = "1.0" encoding = "utf-8" ?> < test > < title >testSAX</ title > < content aa = "1" bb = "2" > < name >hellogv</ name > </ content > </ test > |
解析如上XML的结果图如下:
使用SAX解析,需要定义SAXParserFactory(使应用程序能够配置和获取基于 SAX 的解析器以解析 XML 文档),SAXParser(从各种输入源解析 XML),XMLReader(使用回调函数读取 XML 文档),其中XMLReader是个关键。XMLReader可以为解析XML定义各种回调函数,“条件符合”的时候触发这些回调函数。
1
2
3
4
5
6
|
SAXParserFactory SAXParser XMLReader reader.setContentHandler(handler); reader.parse( new InputSource(testSAX. this .getResources() .openRawResource(R.raw.test))); |
在这段代码里,XMLReader就调用继承DefaultHandler的SAXHandler。DefaultHandler已实现ContentHandler, DTDHandler, EntityResolver, ErrorHandler等接口,包含常见读取XML的操作,具体请看下面的SAXHandler.java源码。
生成XML的结果如下:
上图是读取各节点之后,使用XmlSerializer重新组合并输出XML字符串。
main.xml代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
<? xml version = "1.0" encoding = "utf-8" ?> android:orientation = "vertical" android:layout_width = "fill_parent" android:layout_height = "fill_parent" > < Button android:id = "@+id/btnSAX" android:layout_width = "fill_parent" android:layout_height = "wrap_content" android:text = "使用SAX解析xml" /> < Button android:id = "@+id/btnOutput" android:layout_width = "fill_parent" android:layout_height = "wrap_content" android:text = "生成xml" /> < EditText android:id = "@+id/EditText01" android:layout_width = "fill_parent" android:layout_height = "fill_parent" android:text = "@+id/EditText01" /> </ LinearLayout > |
SAXHandler.java代码:
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
package com.testSAX; import java.util.ArrayList; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; import android.util.Log; public class SAXHandler extends DefaultHandler private ArrayList<String> new ArrayList<String>(); // private ArrayList<Object> new ArrayList<Object>(); // @Override public void startDocument() throws SAXException super .startDocument(); } @Override public void endDocument() throws SAXException super .endDocument(); } @Override public void startElement(String Attributes throws SAXException // keys.add( "startTag" ); values.add(localName); Log.e( "startTag" , // for ( int i 0 ; keys.add( "Attr" ); String[] new String[ 2 ]; str[ 0 ] str[ 1 ] values.add(str); Log.e( "Attr" , 0 ] "=" + 1 ]); } } @Override public void endElement(String throws SAXException // keys.add( "endTag" ); values.add(localName); Log.e( "endTag" , } @Override public void characters( char [] int start, int length) throws SAXException String new String(ch, value if (value.length() 0 ) return ; keys.add( "text" ); values.add(value); Log.e( "text" , } public ArrayList<String> return keys; } public ArrayList<Object> return values; } } |
testSAX.java代码:
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
package com.testSAX; import java.io.StringWriter; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.InputSource; import org.xml.sax.XMLReader; import org.xmlpull.v1.XmlSerializer; import android.app.Activity; import android.os.Bundle; import android.util.Xml; import android.view.View; import android.widget.Button; import android.widget.EditText; public class testSAX extends Activity /** Button EditText SAXHandler new SAXHandler(); @Override public void onCreate(Bundle super .onCreate(savedInstanceState); setContentView(R.layout.main); btnSAX this .findViewById(R.id.btnSAX); btnSAX.setOnClickListener( new ClickEvent()); btnOutput this .findViewById(R.id.btnOutput); btnOutput.setOnClickListener( new ClickEvent()); memo this .findViewById(R.id.EditText01); } class ClickEvent implements View.OnClickListener @Override public void onClick(View if (v // try { SAXParserFactory SAXParser XMLReader reader.setContentHandler(handler); reader.parse( new InputSource(testSAX. this .getResources() .openRawResource(R.raw.test))); } catch (Exception } } else if (v // try { XmlSerializer StringWriter new StringWriter(); try { serializer.setOutput(writer); serializer.startDocument( "UTF-8" , true ); for ( int i 0 ; if (handler.GetKeys().get(i).equals( "startTag" )) serializer.startTag( "" , .GetValues().get(i)); } else if (handler.GetKeys().get(i).equals( "Attr" )) String[] .get(i); serializer.attribute( "" , 0 ], 1 ]); } else if (handler.GetKeys().get(i).equals( "text" )) serializer.text((String) .get(i)); else if (handler.GetKeys().get(i).equals( "endTag" )) serializer.endTag( "" , .GetValues().get(i)); } } serializer.endDocument(); String text "><" , ">/r/n<" ); memo.setText(text); // } catch (Exception throw new RuntimeException(e); } } catch (Exception } } } } } |