HardBirch

Android提高第七篇之XML解析与生成

时间:10-11-12 栏目:安卓入门与提高 作者:张飞不张,文采横飞 评论:22 点击: 7,525 次

       本文使用SAX来解析XML,在Android里面可以使用SAX和DOM,DOM需要把整个XML文件读入内存再解析,比较消耗内存,而SAX基于事件驱动的处理方式,可以在各节点触发回调函数,不过SAX适合节点结构简单的XML文档,复杂的XML文档在后期的节点深度处理会有点麻烦。

本文要解析的test.xml文件如下:








 

解析如上XML的结果如下:

 

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






在这段代码里,XMLReader就调用继承DefaultHandler的SAXHandler。DefaultHandler已实现ContentHandler, DTDHandler, EntityResolver, ErrorHandler等接口,包含常见读取XML的操作,具体请看下面的SAXHandler.java源码。

生成XML的结果如下:

上图是读取各节点之后,使用XmlSerializer重新组合并输出XML字符串。

本文的main.xml代码如下:




<Button android:layout_height="wrap_content"
android:layout_width="fill_parent" android:id="@+id/btnSAX"
android:text="使用SAX解析XML"></Button>
<Button android:layout_height="wrap_content"
android:layout_width="fill_parent" android:text="生成XML" android:id="@+id/btnOutput"></Button>
<EditText android:text="@+id/EditText01" android:id="@+id/EditText01"
android:layout_width="fill_parent" android:layout_height="fill_parent"></EditText>

</LinearLayout>

SAXHandler.java的源码如下:

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的源码如下:

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) {}
}

}

}
}

声明: 本文由( 张飞不张,文采横飞 )原创编译,转载请保留链接: Android提高第七篇之XML解析与生成

Android提高第七篇之XML解析与生成:目前有22 条留言

  1. 22楼
    hmc1985:

    [e01]

    2010-11-12 12:51 [回复]
  2. 21楼
    over1400:

    [e01]
    农民伯伯敬上

    2010-11-12 13:12 [回复]
  3. 20楼
    kf156:

    [e01]虫哥V5

    2010-11-12 13:30 [回复]
  4. 19楼
    JNU_kinke:

    ………

    2010-11-12 14:46 [回复]
  5. 18楼
    yyyay:

    [e01]xuexile

    2010-11-13 15:24 [回复]
  6. 17楼
    javacn_org:

    可是使用 pull 解析,而且pull 才是android官方推荐的 xml 解析方式

    相关文章 xml 解析技术之 pull 解析
    http://www.javacn.org/forum.php?mod=viewthread&amp;tid=9

    2010-11-13 17:27 [回复]
  7. 不错

    2010-11-15 17:08 [回复]
  8. 15楼
    bjwj8:

    [e01]

    2010-11-18 16:53 [回复]
  9. 14楼
    tenseason:

    需要在res下加raw的文件夹

    2010-12-10 10:52 [回复]
  10. 13楼
    tenseason:

    回复 javacn_org:

    如果是数据库用的xml的话的确是。

    2010-12-10 11:37 [回复]
  11. [e01]好东西大家顶起来啊

    2011-04-06 09:53 [回复]
  12. [e01]

    2011-04-06 09:53 [回复]
  13. 10楼
    smileyfei:

    [e01]

    2011-04-07 23:41 [回复]
  14. 9楼
    C1010TV:

    [e01]

    2011-04-11 16:40 [回复]
  15. 8楼
    wtw11897:

    [e01][e03][e04]

    2011-05-15 23:06 [回复]
  16. 为什么一定要在res下加raw的文件夹,命名成其它的文件名都不能支持呢?

    2011-06-02 10:42 [回复]
  17. 6楼
    myuser11:

    [e03]

    2011-06-27 15:01 [回复]
  18. XStream很好用啊

    2011-09-14 02:40 [回复]
  19. 不错的android开发论坛: http://bbs.androidjy.com

    2011-09-14 13:08 [回复]
  20. 地板
    xyylchq:

    学习

    2011-09-25 21:14 [回复]
  21. 板凳
    cdd1992112:

    text=text.replace("><", ">/r/n<");
    应改为:text=text.replace("><", ">rn<");

    2011-12-28 18:07 [回复]
  22. 沙发
    cjl_852006:

    [reply]cdd1992112[/reply]
    正确!

    2012-03-17 15:56 [回复]

发表评论


QQ群互动

Linux系统与内核学习群:194051772

WP建站技术学习交流群:194062106

魔豆之路QR

魔豆的Linux内核之路

魔豆的Linux内核之路

优秀工程师当看优秀书籍

优秀程序员,要看优秀书!

赞助商广告

友荐云推荐