[devdiv精华转载] android开发 四种方式解析字符串----JSON、SAX、DOM、XML

原帖地址:http://www.devdiv.com/forum.php?mod=viewthread&tid=60304&extra=page%3D1%26filter%3Ddigest%26digest%3D1%26digest%3D1

 

当是练习吧,分别以JSON、SAX、DOM、XML(android.util.XML)来解析字符串。
个人感觉这四种方式的实现由难到易的顺序是:SAX→XML→DOM→JSON。

JSON解析的内容如下,文件名为devdiv.json,存于工程的assets目录下:

  1. {
  2.                 "code":"1",
  3.                 "result":{
  4.                         "title":"Devdiv移动开发社区",
  5.                         "title_url":"http://www.devdiv.com/forum.php",
  6.                         "development_forum_name":"开发讨论区",
  7.                         "development_forum":[
  8.                                 {"name":"Windows Phone论坛","url":"http://www.devdiv.com/forum-windows-phone-mobile-1.html"},
  9.                                 {"name":"Android论坛","url":"http://www.devdiv.com/forum-android-1.html"},
  10.                                 {"name":"iOS/iPhone论坛","url":"http://www.devdiv.com/forum-iphone-1.html"}
  11.                                 ]
  12.                 }
  13. }
复制代码

剩下三个解析内容如下,文件名为devdiv.xml,存于工程的assets目录下:

  1. <root>
  2.         <title>Devdiv移动开发社区</title>
  3.         <body>开发讨论区</body>
  4.         <item url="http://www.devdiv.com/forum-windows-phone-mobile-1.html">Windows Phone论坛</item>
  5.         <item url="http://www.devdiv.com/forum-android-1.html">Android论坛</item>
  6.         <item url="http://www.devdiv.com/forum-iphone-1.html">iOS/iPhone论坛</item>
  7. </root>
复制代码

本例子解析后显示效果:
device.png 
代码如下:

  1. package lab.sodino.string;
  2. import java.io.IOException;
  3. import java.io.InputStream;
  4. import java.util.Vector;
  5. import javax.xml.parsers.DocumentBuilder;
  6. import javax.xml.parsers.DocumentBuilderFactory;
  7. import javax.xml.parsers.FactoryConfigurationError;
  8. import javax.xml.parsers.ParserConfigurationException;
  9. import javax.xml.parsers.SAXParser;
  10. import javax.xml.parsers.SAXParserFactory;
  11. import org.json.JSONArray;
  12. import org.json.JSONException;
  13. import org.json.JSONObject;
  14. import org.w3c.dom.Document;
  15. import org.w3c.dom.Element;
  16. import org.w3c.dom.Node;
  17. import org.w3c.dom.NodeList;
  18. import org.xml.sax.Attributes;
  19. import org.xml.sax.SAXException;
  20. import org.xml.sax.helpers.DefaultHandler;
  21. import android.app.Activity;
  22. import android.graphics.Typeface;
  23. import android.os.Bundle;
  24. import android.text.SpannableString;
  25. import android.text.Spanned;
  26. import android.text.method.LinkMovementMethod;
  27. import android.text.style.StyleSpan;
  28. import android.text.style.URLSpan;
  29. import android.util.Log;
  30. import android.view.View;
  31. import android.widget.Button;
  32. import android.widget.TextView;
  33. public class TextAct extends Activity {
  34.         public static final String TAG = "ANDROID_LAB";
  35.         private Button btnJSON;
  36.         private Button btnSAX;
  37.         private Button btnDOM;
  38.         private Button btnXML;
  39.         private BtnListener btnListener;
  40.         private TextView txtInfo;
  41.         public void onCreate(Bundle savedInstanceState) {
  42.                 super.onCreate(savedInstanceState);
  43.                 setContentView(R.layout.main);
  44.                 btnListener = new BtnListener();
  45.                 btnJSON = (Button) findViewById(R.id.btnJSON);
  46.                 btnSAX = (Button) findViewById(R.id.btnSAX);
  47.                 btnDOM = (Button) findViewById(R.id.btnDOM);
  48.                 btnXML = (Button) findViewById(R.id.btnXML);
  49.                 btnJSON.setOnClickListener(btnListener);
  50.                 btnSAX.setOnClickListener(btnListener);
  51.                 btnDOM.setOnClickListener(btnListener);
  52.                 btnXML.setOnClickListener(btnListener);
  53.                 txtInfo = (TextView) findViewById(R.id.txtInfo);
  54.         }
  55.         private void inflateTextViewByBean(Bean bean) {
  56.                 int spanCount = 4;
  57.                 int[] start = new int[spanCount];
  58.                 int[] end = new int[spanCount];
  59.                 StringBuffer buffer = new StringBuffer();
  60.                 buffer.append(bean.type + "\n");
  61.                 buffer.append(bean.title + "\n");
  62.                 start[0] = buffer.length();
  63.                 buffer.append(bean.development_forum_name + "\n");
  64.                 end[0] = buffer.length();
  65.                 for (int i = 0; i < bean.vecName.size(); i++) {
  66.                         start[i + 1] = buffer.length();
  67.                         buffer.append(bean.vecName.get(i) + "\n");
  68.                         end[i + 1] = buffer.length();
  69.                 }
  70.                 SpannableString spannableString = new SpannableString(buffer.toString());
  71.                 spannableString.setSpan(new StyleSpan(Typeface.ITALIC), start[0], end[0],
  72.                                 Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
  73.                 for (int i = 0; i < bean.vecName.size(); i++) {
  74.                         spannableString.setSpan(new URLSpan(bean.vecUrl.get(i)), start[i + 1], end[i + 1],
  75.                                         Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
  76.                 }
  77.                 txtInfo.setText(spannableString);
  78.                 txtInfo.setMovementMethod(LinkMovementMethod.getInstance());
  79.         }
  80.         class BtnListener implements Button.OnClickListener {
  81.                 public void onClick(View view) {
  82.                         if (view == btnJSON) {
  83.                                 showInfoFromJSON();
  84.                         } else if (view == btnSAX) {
  85.                                 showInfoFromSAXParser();
  86.                         } else if (view == btnDOM) {
  87.                                 showInfoFromDOM();
  88.                         } else if (view == btnXML) {
  89.                                 showInfoFromXML();
  90.                         }
  91.                 }
  92.         }
  93.         public void showInfoFromJSON() {
  94.                 Bean bean = new Bean();
  95.                 bean.type = "Inflated by JSON\n";
  96.                 String content = "";
  97.                 InputStream is = null;
  98.                 try {
  99.                         is = getAssets().open("devdiv.json");
  100.                         byte[] data = new byte[is.available()];
  101.                         is.read(data);
  102.                         content = new String(data);
  103.                         Log.d(TAG, "content=" + content);
  104.                         JSONObject jsonContent = new JSONObject(content);
  105.                         int code = jsonContent.getInt("code");
  106.                         // 假设默认code为1时才是正确的json数据。
  107.                         if (code == 1) {
  108.                                 JSONObject jsonResult = jsonContent.getJSONObject("result");
  109.                                 bean.title = jsonResult.getString("title");
  110.                                 bean.development_forum_name = jsonResult.getString("development_forum_name");
  111.                                 bean.vecName = new Vector<String>();
  112.                                 bean.vecUrl = new Vector<String>();
  113.                                 JSONArray devArr = jsonResult.getJSONArray("development_forum");
  114.                                 String tmp = "";
  115.                                 for (int i = 0; i < devArr.length(); i++) {
  116.                                         JSONObject obj = devArr.getJSONObject(i);
  117.                                         tmp = obj.getString("name");
  118.                                         bean.vecName.add(tmp);
  119.                                         tmp = obj.getString("url");
  120.                                         bean.vecUrl.add(tmp);
  121.                                 }
  122.                                 inflateTextViewByBean(bean);
  123.                         } else {
  124.                                 Log.d(TAG, "A error occur when parse a json file.");
  125.                         }
  126.                 } catch (IOException e) {
  127.                         e.printStackTrace();
  128.                 } catch (JSONException e) {
  129.                         e.printStackTrace();
  130.                 } finally {
  131.                         try {
  132.                                 if (is != null) {
  133.                                         is.close();
  134.                                 }
  135.                         } catch (IOException ie) {
  136.                                 ie.printStackTrace();
  137.                         }
  138.                 }
  139.         }
  140.         public void showInfoFromXML() {
  141.                 Bean bean = new Bean();
  142.                 bean.type = "Inflated by XML\n";
  143.                 bean.vecName = new Vector<String>();
  144.                 bean.vecUrl = new Vector<String>();
  145.                 MyXMLHandler xmlHandler = null;
  146.                 InputStream is = null;
  147.                 xmlHandler = new MyXMLHandler(bean);
  148.                 try {
  149.                         is = getAssets().open("devdiv.xml");
  150.                         // 一句话就OK了。
  151.                         android.util.Xml.parse(is, android.util.Xml.Encoding.UTF_8, xmlHandler);
  152.                 } catch (IOException e) {
  153.                         e.printStackTrace();
  154.                 } catch (SAXException e) {
  155.                         e.printStackTrace();
  156.                 } finally {
  157.                         try {
  158.                                 if (is != null) {
  159.                                         is.close();
  160.                                 }
  161.                         } catch (IOException ie) {
  162.                                 ie.printStackTrace();
  163.                         }
  164.                 }
  165.                 inflateTextViewByBean(bean);
  166.         }
  167.         public void showInfoFromDOM() {
  168.                 Bean bean = new Bean();
  169.                 bean.type = "Inflated by DOM\n";
  170.                 bean.vecName = new Vector<String>();
  171.                 bean.vecUrl = new Vector<String>();
  172.                 InputStream is = null;
  173.                 DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
  174.                 try {
  175.                         is = getAssets().open("devdiv.xml");
  176.                         NodeList list = null;
  177.                         DocumentBuilder domBuilder = domFactory.newDocumentBuilder();
  178.                         Document doc = domBuilder.parse(is);
  179.                         // 获取根目录
  180.                         Element rootElement = doc.getDocumentElement();
  181.                         // 输出[rootElement=root]
  182.                         Log.d(TAG, "rootElement=" + rootElement.getNodeName());
  183.                         list = rootElement.getElementsByTagName("title");
  184.                         // 在已提前获只有一个title的情况下直接去取list.item(0)
  185.                         bean.title = list.item(0).getTextContent();
  186.                         // 在已提前获只有一个body的情况下直接去取list.item(0)
  187.                         list = rootElement.getElementsByTagName("body");
  188.                         bean.development_forum_name = list.item(0).getTextContent();
  189.                         // 多个item的读取情形
  190.                         list = rootElement.getElementsByTagName("item");
  191.                         for (int i = 0; i < list.getLength(); i++) {
  192.                                 Node node = list.item(i);
  193.                                 bean.vecUrl.add(node.getAttributes().item(0).getTextContent());
  194.                                 bean.vecName.add(node.getTextContent());
  195.                         }
  196.                 } catch (ParserConfigurationException e) {
  197.                         e.printStackTrace();
  198.                 } catch (IOException e) {
  199.                         e.printStackTrace();
  200.                 } catch (SAXException e) {
  201.                         e.printStackTrace();
  202.                 } finally {
  203.                         try {
  204.                                 if (is != null) {
  205.                                         is.close();
  206.                                 }
  207.                         } catch (IOException ie) {
  208.                                 ie.printStackTrace();
  209.                         }
  210.                 }
  211.                 inflateTextViewByBean(bean);
  212.         }
  213.         public void showInfoFromSAXParser() {
  214.                 Bean bean = new Bean();
  215.                 bean.vecName = new Vector<String>();
  216.                 bean.vecUrl = new Vector<String>();
  217.                 bean.type = "Inflated by SAXParser\n";
  218.                 InputStream is = null;
  219.                 SAXParser parser = null;
  220.                 MyXMLHandler xmlHandler = null;
  221.                 try {
  222.                         parser = SAXParserFactory.newInstance().newSAXParser();
  223.                         xmlHandler = new MyXMLHandler(bean);
  224.                         is = getAssets().open("devdiv.xml");
  225.                         parser.parse(is, xmlHandler);
  226.                         inflateTextViewByBean(bean);
  227.                 } catch (IOException ie) {
  228.                         ie.printStackTrace();
  229.                 } catch (ParserConfigurationException e) {
  230.                         e.printStackTrace();
  231.                 } catch (SAXException e) {
  232.                         e.printStackTrace();
  233.                 } catch (FactoryConfigurationError e) {
  234.                         e.printStackTrace();
  235.                 } finally {
  236.                         try {
  237.                                 if (is != null) {
  238.                                         is.close();
  239.                                 }
  240.                         } catch (IOException ie) {
  241.                                 ie.printStackTrace();
  242.                         }
  243.                 }
  244.         }
  245.         class MyXMLHandler extends DefaultHandler {
  246.                 Bean bean;
  247.                 String currentElement;
  248.                 public MyXMLHandler(Bean bean) {
  249.                         MyXMLHandler.this.bean = bean;
  250.                 }
  251.                 public void startDocument() throws SAXException {
  252.                         Log.d(TAG, "MyXMLHandler startDocument");
  253.                 }
  254.                 public void endDocument() throws SAXException {
  255.                         Log.d(TAG, "MyXMLHandler endDocument");
  256.                 }
  257.                 public void startElement(String uri, String localName, String qName, Attributes atts)
  258.                                 throws SAXException {
  259.                         // Log.d(TAG, "MyXMLHandler startElement");
  260.                         currentElement = localName;
  261.                         if (localName.equals("item")) {
  262.                                 if (atts != null) {
  263.                                         for (int i = 0; i < atts.getLength(); i++) {
  264.                                                 // 本例中atts.getLength()值为1
  265.                                                 bean.vecUrl.add(atts.getValue(i));
  266.                                                 Log.d(TAG, "add url[" + atts.getValue(i) + "]");
  267.                                         }
  268.                                 }
  269.                         }
  270.                 }
  271.                 public void characters(char[] ch, int start, int length) throws SAXException {
  272.                         String str = new String(ch, start, length);
  273.                         // Log.d(TAG, "MyXMLHandler characters start=" + start + " len=" +
  274.                         // length + " str[" + str
  275.                         // + "]");
  276.                         if (currentElement != null) {
  277.                                 String tmp = new String(ch, start, length);
  278.                                 if (currentElement.equals("title")) {
  279.                                         bean.title = tmp;
  280.                                 } else if (currentElement.equals("body")) {
  281.                                         bean.development_forum_name = tmp;
  282.                                 } else if (currentElement.equals("item")) {
  283.                                         bean.vecName.add(tmp);
  284.                                         Log.d(TAG, "add name[" + tmp + "]");
  285.                                 }
  286.                         }
  287.                 }
  288.                 public void endElement(String uri, String localName, String qName) throws SAXException {
  289.                         Log.d(TAG, "MyXMLHandler endDocument");
  290.                         currentElement = null;
  291.                 }
  292.         }
  293.         class Bean {
  294.                 String type;
  295.                 String title;
  296.                 String development_forum_name;
  297.                 Vector<String> vecName;
  298.                 Vector<String> vecUrl;
  299.         }
  300. }
复制代码

 

DOM解析中的Node.etTextContent()要求api-level至少为8。
现补充level为8以下的解析方法:

  1.         public void showInfoFromDOM() {
  2.                 Bean bean = new Bean();
  3.                 bean.type = "Inflated by DOM\n";
  4.                 bean.vecName = new Vector<String>();
  5.                 bean.vecUrl = new Vector<String>();
  6.                 InputStream is = null;
  7.                 DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
  8.                 try {
  9.                         is = getAssets().open("devdiv.xml");
  10.                         NodeList list = null;
  11.                         DocumentBuilder domBuilder = domFactory.newDocumentBuilder();
  12.                         Document doc = domBuilder.parse(is);
  13.                         // 获取根目录
  14.                         Element rootElement = doc.getDocumentElement();
  15.                         // 输出[rootElement=root]
  16.                         Log.d(TAG, "rootElement=" + rootElement.getNodeName());
  17.                         list = rootElement.getElementsByTagName("title");
  18.                         if (Integer.parseInt(Build.VERSION.SDK) >= 8) {
  19.                                 // 在已提前获只有一个title的情况下直接去取list.item(0)
  20.                                 bean.title = list.item(0).getTextContent();
  21.                                 // 在已提前获只有一个body的情况下直接去取list.item(0)
  22.                                 list = rootElement.getElementsByTagName("body");
  23.                                 bean.development_forum_name = list.item(0).getTextContent();
  24.                                 // 多个item的读取情形
  25.                                 list = rootElement.getElementsByTagName("item");
  26.                                 for (int i = 0; i < list.getLength(); i++) {
  27.                                         Node node = list.item(i);
  28.                                         bean.vecUrl.add(node.getAttributes().item(0).getTextContent());
  29.                                         bean.vecName.add(node.getTextContent());
  30.                                 }
  31.                         } else {
  32.                                 // 在已提前获只有一个title的情况下直接去取list.item(0)
  33.                                 bean.title = list.item(0).getFirstChild().getNodeValue();
  34.                                 // 在已提前获只有一个body的情况下直接去取list.item(0)
  35.                                 list = rootElement.getElementsByTagName("body");
  36.                                 bean.development_forum_name = list.item(0).getFirstChild().getNodeValue();
  37.                                 // 多个item的读取情形
  38.                                 list = rootElement.getElementsByTagName("item");
  39.                                 for (int i = 0; i < list.getLength(); i++) {
  40.                                         Node node = list.item(i);
  41.                                         bean.vecUrl.add(node.getAttributes().getNamedItem("url").getNodeValue());
  42.                                         bean.vecName.add(node.getFirstChild().getNodeValue());
  43.                                 }
  44.                         }
  45.                 } catch (ParserConfigurationException e) {
  46.                         e.printStackTrace();
  47.                 } catch (IOException e) {
  48.                         e.printStackTrace();
  49.                 } catch (SAXException e) {
  50.                         e.printStackTrace();
  51.                 } finally {
  52.                         try {
  53.                                 if (is != null) {
  54.                                         is.close();
  55.                                 }
  56.                         } catch (IOException ie) {
  57.                                 ie.printStackTrace();
  58.                         }
  59.                 }
  60.                 inflateTextViewByBean(bean);
  61.         }

复制代码

 

 

 

 

posted on 2011-12-06 13:09  Evalon  阅读(445)  评论(0)    收藏  举报

导航