[devdiv精华转载] android开发 四种方式解析字符串----JSON、SAX、DOM、XML
当是练习吧,分别以JSON、SAX、DOM、XML(android.util.XML)来解析字符串。
个人感觉这四种方式的实现由难到易的顺序是:SAX→XML→DOM→JSON。
JSON解析的内容如下,文件名为devdiv.json,存于工程的assets目录下:
- {
- "code":"1",
- "result":{
- "title":"Devdiv移动开发社区",
- "title_url":"http://www.devdiv.com/forum.php",
- "development_forum_name":"开发讨论区",
- "development_forum":[
- {"name":"Windows Phone论坛","url":"http://www.devdiv.com/forum-windows-phone-mobile-1.html"},
- {"name":"Android论坛","url":"http://www.devdiv.com/forum-android-1.html"},
- {"name":"iOS/iPhone论坛","url":"http://www.devdiv.com/forum-iphone-1.html"}
- ]
- }
- }
剩下三个解析内容如下,文件名为devdiv.xml,存于工程的assets目录下:
- <root>
- <title>Devdiv移动开发社区</title>
- <body>开发讨论区</body>
- <item url="http://www.devdiv.com/forum-windows-phone-mobile-1.html">Windows Phone论坛</item>
- <item url="http://www.devdiv.com/forum-android-1.html">Android论坛</item>
- <item url="http://www.devdiv.com/forum-iphone-1.html">iOS/iPhone论坛</item>
- </root>
本例子解析后显示效果:
代码如下:
- package lab.sodino.string;
- import java.io.IOException;
- import java.io.InputStream;
- import java.util.Vector;
- import javax.xml.parsers.DocumentBuilder;
- import javax.xml.parsers.DocumentBuilderFactory;
- import javax.xml.parsers.FactoryConfigurationError;
- import javax.xml.parsers.ParserConfigurationException;
- import javax.xml.parsers.SAXParser;
- import javax.xml.parsers.SAXParserFactory;
- import org.json.JSONArray;
- import org.json.JSONException;
- import org.json.JSONObject;
- import org.w3c.dom.Document;
- import org.w3c.dom.Element;
- import org.w3c.dom.Node;
- import org.w3c.dom.NodeList;
- import org.xml.sax.Attributes;
- import org.xml.sax.SAXException;
- import org.xml.sax.helpers.DefaultHandler;
- import android.app.Activity;
- import android.graphics.Typeface;
- import android.os.Bundle;
- import android.text.SpannableString;
- import android.text.Spanned;
- import android.text.method.LinkMovementMethod;
- import android.text.style.StyleSpan;
- import android.text.style.URLSpan;
- import android.util.Log;
- import android.view.View;
- import android.widget.Button;
- import android.widget.TextView;
- public class TextAct extends Activity {
- public static final String TAG = "ANDROID_LAB";
- private Button btnJSON;
- private Button btnSAX;
- private Button btnDOM;
- private Button btnXML;
- private BtnListener btnListener;
- private TextView txtInfo;
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- btnListener = new BtnListener();
- btnJSON = (Button) findViewById(R.id.btnJSON);
- btnSAX = (Button) findViewById(R.id.btnSAX);
- btnDOM = (Button) findViewById(R.id.btnDOM);
- btnXML = (Button) findViewById(R.id.btnXML);
- btnJSON.setOnClickListener(btnListener);
- btnSAX.setOnClickListener(btnListener);
- btnDOM.setOnClickListener(btnListener);
- btnXML.setOnClickListener(btnListener);
- txtInfo = (TextView) findViewById(R.id.txtInfo);
- }
- private void inflateTextViewByBean(Bean bean) {
- int spanCount = 4;
- int[] start = new int[spanCount];
- int[] end = new int[spanCount];
- StringBuffer buffer = new StringBuffer();
- buffer.append(bean.type + "\n");
- buffer.append(bean.title + "\n");
- start[0] = buffer.length();
- buffer.append(bean.development_forum_name + "\n");
- end[0] = buffer.length();
- for (int i = 0; i < bean.vecName.size(); i++) {
- start[i + 1] = buffer.length();
- buffer.append(bean.vecName.get(i) + "\n");
- end[i + 1] = buffer.length();
- }
- SpannableString spannableString = new SpannableString(buffer.toString());
- spannableString.setSpan(new StyleSpan(Typeface.ITALIC), start[0], end[0],
- Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
- for (int i = 0; i < bean.vecName.size(); i++) {
- spannableString.setSpan(new URLSpan(bean.vecUrl.get(i)), start[i + 1], end[i + 1],
- Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
- }
- txtInfo.setText(spannableString);
- txtInfo.setMovementMethod(LinkMovementMethod.getInstance());
- }
- class BtnListener implements Button.OnClickListener {
- public void onClick(View view) {
- if (view == btnJSON) {
- showInfoFromJSON();
- } else if (view == btnSAX) {
- showInfoFromSAXParser();
- } else if (view == btnDOM) {
- showInfoFromDOM();
- } else if (view == btnXML) {
- showInfoFromXML();
- }
- }
- }
- public void showInfoFromJSON() {
- Bean bean = new Bean();
- bean.type = "Inflated by JSON\n";
- String content = "";
- InputStream is = null;
- try {
- is = getAssets().open("devdiv.json");
- byte[] data = new byte[is.available()];
- is.read(data);
- content = new String(data);
- Log.d(TAG, "content=" + content);
- JSONObject jsonContent = new JSONObject(content);
- int code = jsonContent.getInt("code");
- // 假设默认code为1时才是正确的json数据。
- if (code == 1) {
- JSONObject jsonResult = jsonContent.getJSONObject("result");
- bean.title = jsonResult.getString("title");
- bean.development_forum_name = jsonResult.getString("development_forum_name");
- bean.vecName = new Vector<String>();
- bean.vecUrl = new Vector<String>();
- JSONArray devArr = jsonResult.getJSONArray("development_forum");
- String tmp = "";
- for (int i = 0; i < devArr.length(); i++) {
- JSONObject obj = devArr.getJSONObject(i);
- tmp = obj.getString("name");
- bean.vecName.add(tmp);
- tmp = obj.getString("url");
- bean.vecUrl.add(tmp);
- }
- inflateTextViewByBean(bean);
- } else {
- Log.d(TAG, "A error occur when parse a json file.");
- }
- } catch (IOException e) {
- e.printStackTrace();
- } catch (JSONException e) {
- e.printStackTrace();
- } finally {
- try {
- if (is != null) {
- is.close();
- }
- } catch (IOException ie) {
- ie.printStackTrace();
- }
- }
- }
- public void showInfoFromXML() {
- Bean bean = new Bean();
- bean.type = "Inflated by XML\n";
- bean.vecName = new Vector<String>();
- bean.vecUrl = new Vector<String>();
- MyXMLHandler xmlHandler = null;
- InputStream is = null;
- xmlHandler = new MyXMLHandler(bean);
- try {
- is = getAssets().open("devdiv.xml");
- // 一句话就OK了。
- android.util.Xml.parse(is, android.util.Xml.Encoding.UTF_8, xmlHandler);
- } catch (IOException e) {
- e.printStackTrace();
- } catch (SAXException e) {
- e.printStackTrace();
- } finally {
- try {
- if (is != null) {
- is.close();
- }
- } catch (IOException ie) {
- ie.printStackTrace();
- }
- }
- inflateTextViewByBean(bean);
- }
- public void showInfoFromDOM() {
- Bean bean = new Bean();
- bean.type = "Inflated by DOM\n";
- bean.vecName = new Vector<String>();
- bean.vecUrl = new Vector<String>();
- InputStream is = null;
- DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
- try {
- is = getAssets().open("devdiv.xml");
- NodeList list = null;
- DocumentBuilder domBuilder = domFactory.newDocumentBuilder();
- Document doc = domBuilder.parse(is);
- // 获取根目录
- Element rootElement = doc.getDocumentElement();
- // 输出[rootElement=root]
- Log.d(TAG, "rootElement=" + rootElement.getNodeName());
- list = rootElement.getElementsByTagName("title");
- // 在已提前获只有一个title的情况下直接去取list.item(0)
- bean.title = list.item(0).getTextContent();
- // 在已提前获只有一个body的情况下直接去取list.item(0)
- list = rootElement.getElementsByTagName("body");
- bean.development_forum_name = list.item(0).getTextContent();
- // 多个item的读取情形
- list = rootElement.getElementsByTagName("item");
- for (int i = 0; i < list.getLength(); i++) {
- Node node = list.item(i);
- bean.vecUrl.add(node.getAttributes().item(0).getTextContent());
- bean.vecName.add(node.getTextContent());
- }
- } catch (ParserConfigurationException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- } catch (SAXException e) {
- e.printStackTrace();
- } finally {
- try {
- if (is != null) {
- is.close();
- }
- } catch (IOException ie) {
- ie.printStackTrace();
- }
- }
- inflateTextViewByBean(bean);
- }
- public void showInfoFromSAXParser() {
- Bean bean = new Bean();
- bean.vecName = new Vector<String>();
- bean.vecUrl = new Vector<String>();
- bean.type = "Inflated by SAXParser\n";
- InputStream is = null;
- SAXParser parser = null;
- MyXMLHandler xmlHandler = null;
- try {
- parser = SAXParserFactory.newInstance().newSAXParser();
- xmlHandler = new MyXMLHandler(bean);
- is = getAssets().open("devdiv.xml");
- parser.parse(is, xmlHandler);
- inflateTextViewByBean(bean);
- } catch (IOException ie) {
- ie.printStackTrace();
- } catch (ParserConfigurationException e) {
- e.printStackTrace();
- } catch (SAXException e) {
- e.printStackTrace();
- } catch (FactoryConfigurationError e) {
- e.printStackTrace();
- } finally {
- try {
- if (is != null) {
- is.close();
- }
- } catch (IOException ie) {
- ie.printStackTrace();
- }
- }
- }
- class MyXMLHandler extends DefaultHandler {
- Bean bean;
- String currentElement;
- public MyXMLHandler(Bean bean) {
- MyXMLHandler.this.bean = bean;
- }
- public void startDocument() throws SAXException {
- Log.d(TAG, "MyXMLHandler startDocument");
- }
- public void endDocument() throws SAXException {
- Log.d(TAG, "MyXMLHandler endDocument");
- }
- public void startElement(String uri, String localName, String qName, Attributes atts)
- throws SAXException {
- // Log.d(TAG, "MyXMLHandler startElement");
- currentElement = localName;
- if (localName.equals("item")) {
- if (atts != null) {
- for (int i = 0; i < atts.getLength(); i++) {
- // 本例中atts.getLength()值为1
- bean.vecUrl.add(atts.getValue(i));
- Log.d(TAG, "add url[" + atts.getValue(i) + "]");
- }
- }
- }
- }
- public void characters(char[] ch, int start, int length) throws SAXException {
- String str = new String(ch, start, length);
- // Log.d(TAG, "MyXMLHandler characters start=" + start + " len=" +
- // length + " str[" + str
- // + "]");
- if (currentElement != null) {
- String tmp = new String(ch, start, length);
- if (currentElement.equals("title")) {
- bean.title = tmp;
- } else if (currentElement.equals("body")) {
- bean.development_forum_name = tmp;
- } else if (currentElement.equals("item")) {
- bean.vecName.add(tmp);
- Log.d(TAG, "add name[" + tmp + "]");
- }
- }
- }
- public void endElement(String uri, String localName, String qName) throws SAXException {
- Log.d(TAG, "MyXMLHandler endDocument");
- currentElement = null;
- }
- }
- class Bean {
- String type;
- String title;
- String development_forum_name;
- Vector<String> vecName;
- Vector<String> vecUrl;
- }
- }
DOM解析中的Node.etTextContent()要求api-level至少为8。
现补充level为8以下的解析方法:
- public void showInfoFromDOM() {
- Bean bean = new Bean();
- bean.type = "Inflated by DOM\n";
- bean.vecName = new Vector<String>();
- bean.vecUrl = new Vector<String>();
- InputStream is = null;
- DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
- try {
- is = getAssets().open("devdiv.xml");
- NodeList list = null;
- DocumentBuilder domBuilder = domFactory.newDocumentBuilder();
- Document doc = domBuilder.parse(is);
- // 获取根目录
- Element rootElement = doc.getDocumentElement();
- // 输出[rootElement=root]
- Log.d(TAG, "rootElement=" + rootElement.getNodeName());
- list = rootElement.getElementsByTagName("title");
- if (Integer.parseInt(Build.VERSION.SDK) >= 8) {
- // 在已提前获只有一个title的情况下直接去取list.item(0)
- bean.title = list.item(0).getTextContent();
- // 在已提前获只有一个body的情况下直接去取list.item(0)
- list = rootElement.getElementsByTagName("body");
- bean.development_forum_name = list.item(0).getTextContent();
- // 多个item的读取情形
- list = rootElement.getElementsByTagName("item");
- for (int i = 0; i < list.getLength(); i++) {
- Node node = list.item(i);
- bean.vecUrl.add(node.getAttributes().item(0).getTextContent());
- bean.vecName.add(node.getTextContent());
- }
- } else {
- // 在已提前获只有一个title的情况下直接去取list.item(0)
- bean.title = list.item(0).getFirstChild().getNodeValue();
- // 在已提前获只有一个body的情况下直接去取list.item(0)
- list = rootElement.getElementsByTagName("body");
- bean.development_forum_name = list.item(0).getFirstChild().getNodeValue();
- // 多个item的读取情形
- list = rootElement.getElementsByTagName("item");
- for (int i = 0; i < list.getLength(); i++) {
- Node node = list.item(i);
- bean.vecUrl.add(node.getAttributes().getNamedItem("url").getNodeValue());
- bean.vecName.add(node.getFirstChild().getNodeValue());
- }
- }
- } catch (ParserConfigurationException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- } catch (SAXException e) {
- e.printStackTrace();
- } finally {
- try {
- if (is != null) {
- is.close();
- }
- } catch (IOException ie) {
- ie.printStackTrace();
- }
- }
- inflateTextViewByBean(bean);
- }
复制代码
浙公网安备 33010602011771号