7.XML的解析与生成

本文使用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 >
         < url >http://www.android-study.com</ url >
     </ content >
</ test >

解析如上XML的结果图如下:

解析xml

使用SAX解析,需要定义SAXParserFactory(使应用程序能够配置和获取基于 SAX 的解析器以解析 XML 文档),SAXParser(从各种输入源解析 XML),XMLReader(使用回调函数读取 XML 文档),其中XMLReader是个关键。XMLReader可以为解析XML定义各种回调函数,“条件符合”的时候触发这些回调函数。

?
1
2
3
4
5
6
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
XMLReader reader = parser.getXMLReader();
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的结果如下:

生成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" ?>
< LinearLayout  xmlns:android = "http://schemas.android.com/apk/res/android"
     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> keys =  new  ArrayList<String>(); // 保存字段名称
     private  ArrayList<Object> values =  new  ArrayList<Object>(); // 保存值
 
     @Override
     public  void  startDocument()  throws  SAXException {
         super .startDocument();
     }
 
     @Override
     public  void  endDocument()  throws  SAXException {
         super .endDocument();
     }
 
     @Override
     public  void  startElement(String uri, String localName, String qName,
             Attributes attributes)  throws  SAXException {
         // 保存开始标记
         keys.add( "startTag" );
         values.add(localName);
 
         Log.e( "startTag" , localName);
         // 保存属性值
         for  ( int  i =  0 ; i < attributes.getLength(); i++) {
             keys.add( "Attr" );
             String[] str =  new  String[ 2 ];
             str[ 0 ] = attributes.getLocalName(i);
             str[ 1 ] = attributes.getValue(i);
             values.add(str);
             Log.e( "Attr" , str[ 0 ] +  "="  + str[ 1 ]);
         }
     }
 
     @Override
     public  void  endElement(String uri, String localName, String qName)
             throws  SAXException {
         // 保存结束标记
         keys.add( "endTag" );
         values.add(localName);
         Log.e( "endTag" , localName);
     }
 
     @Override
     public  void  characters( char [] ch,  int  start,  int  length)
             throws  SAXException {
         String value =  new  String(ch, start, length);
         value = value.trim();
         if  (value.length() ==  0 )
             return ;
 
         keys.add( "text" );
         values.add(value);
         Log.e( "text" , value);
     }
 
     public  ArrayList<String> GetKeys() {
         return  keys;
     }
 
     public  ArrayList<Object> GetValues() {
         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 {
     /** Called when the activity is first created. */
     Button btnSAX, btnOutput;
     EditText memo;
     SAXHandler handler =  new  SAXHandler();
 
     @Override
     public  void  onCreate(Bundle savedInstanceState) {
         super .onCreate(savedInstanceState);
         setContentView(R.layout.main);
         btnSAX = (Button)  this .findViewById(R.id.btnSAX);
         btnSAX.setOnClickListener( new  ClickEvent());
         btnOutput = (Button)  this .findViewById(R.id.btnOutput);
         btnOutput.setOnClickListener( new  ClickEvent());
         memo = (EditText)  this .findViewById(R.id.EditText01);
 
     }
 
     class  ClickEvent  implements  View.OnClickListener {
 
         @Override
         public  void  onClick(View v) {
             if  (v == btnSAX) { // 解析xml,并保存标记,属性等值
                 try  {
                     SAXParserFactory factory = SAXParserFactory.newInstance();
                     SAXParser parser = factory.newSAXParser();
                     XMLReader reader = parser.getXMLReader();
                     reader.setContentHandler(handler);
                     reader.parse( new  InputSource(testSAX. this .getResources()
                             .openRawResource(R.raw.test)));
                 catch  (Exception ee) {
                 }
             else  if  (v == btnOutput) { // 生成xml
                 try  {
                     XmlSerializer serializer = Xml.newSerializer();
                     StringWriter writer =  new  StringWriter();
                     try  {
                         serializer.setOutput(writer);
                         serializer.startDocument( "UTF-8" true );
 
                         for  ( int  i =  0 ; i < handler.GetKeys().size(); i++) {
                             if  (handler.GetKeys().get(i).equals( "startTag" )) {
                                 serializer.startTag( "" , (String) handler
                                         .GetValues().get(i));
                             else  if (handler.GetKeys().get(i).equals( "Attr" )) {
                                 String[] str = (String[]) handler.GetValues()
                                         .get(i);
                                 serializer.attribute( "" , str[ 0 ], str[ 1 ]);
                             else  if (handler.GetKeys().get(i).equals( "text" ))
                                 serializer.text((String) handler.GetValues()
                                         .get(i));
                             else  if (handler.GetKeys().get(i).equals( "endTag" )) {
                                 serializer.endTag( "" , (String) handler
                                         .GetValues().get(i));
                             }
                         }
                         serializer.endDocument();
                         String text = writer.toString();
                         text = text.replace( "><" ">/r/n<" );
                         memo.setText(text); // 输出到文本框
                     catch  (Exception e) {
                         throw  new  RuntimeException(e);
                     }
 
                 catch  (Exception e) {
                 }
             }
 
         }
 
     }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值