Android数据解析 :XML

jimmychen 8年前
   <p>什么是可扩展标记语言?</p>    <ul>     <li> <p>可扩展标记语言是一种很像 <a href="/misc/goto?guid=4959716866655362142" rel="nofollow,noindex">超文本标记语言</a> 的标记语言</p> </li>     <li> <p>它的设计宗旨是 <em>传输数据</em> ,而不是 <em>显示数据</em></p> </li>     <li> <p>它的标签没有被预定义。您需要自行定义标签</p> </li>     <li> <p>它被设计为具有自我描述性</p> </li>     <li> <p>它是W3C的推荐标准</p> </li>    </ul>    <p>Android中解析XML数据的三种方式 :</p>    <ul>     <li> <p>SAX解析<br> (Simple API for XML)事件驱动,解析速度快,占用内存少</p> </li>     <li> <p>DOM解析<br> 文档对象模型(Document Object Model)将xml文件全部载入,组装成一颗dom树,然后通过节点以及节点之间的关系来解析xml文件</p> </li>     <li> <p>PULL解析<br> 事件驱动, 在解析过程中, 我们需要自己获取产生的事件然后做相应的操作. Android系统内部在解析各种XML时是用PULL解析器</p> </li>    </ul>    <h2><strong>效果展示</strong></h2>    <p style="text-align:center"><img src="https://simg.open-open.com/show/e1754e229a56c002854bc95d459f07ab.gif"></p>    <p style="text-align:center">xml.gif</p>    <h2><strong>代码</strong></h2>    <h3><strong>准备工作</strong></h3>    <ul>     <li> <p style="text-align:left">users.xml(要解析的xml文件)</p> </li>    </ul>    <p style="text-align:left"><strong>目录结构</strong></p>    <p style="text-align:center"> </p>    <p style="text-align:left">目录结构</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/f3eb2744e63c852a6436d300f0e1f4c6.png"></p>    <p style="text-align:center">Paste_Image.png</p>    <pre>  <code class="language-java"><?xml version="1.0" encoding="utf-8"?>  <users>      <user id="1">          <name>保罗</name>          <age>10</age>          <sex>男</sex>      </user>      <user id="2">          <name>金宝</name>          <age>30</age>          <sex>男</sex>      </user>      <user id="3">          <name>缺心</name>          <age>18</age>          <sex>女</sex>      </user>  </users></code></pre>    <ul>     <li> <p>User.java类</p> <p>( 略 )</p> </li>     <li> <p>定义一个接口IUserParser.java</p> </li>    </ul>    <pre>  <code class="language-java">package com.lyp.xml;    import java.io.InputStream;  import java.util.List;    /**   * Created by ${思格斯} on 2016/9/22 0022.   */  public interface IUserParser {      //解析输入流 得到User对象集合      List<User> parse(InputStream is) throws Exception;  }</code></pre>    <h3><strong>界面布局文件</strong></h3>    <ul>     <li>activty_main.xml</li>    </ul>    <pre>  <code class="language-java"><?xml version="1.0" encoding="utf-8"?>  <LinearLayout      xmlns:android="http://schemas.android.com/apk/res/android"      android:orientation="vertical"      android:layout_width="match_parent"      android:layout_height="match_parent"      android:padding="5dp">        <Button          android:id="@+id/btn_sax"          android:text="SAXParser"          android:textSize="25sp"          android:textAllCaps="false"          android:layout_width="match_parent"          android:layout_height="wrap_content"/>      <Button          android:id="@+id/btn_dom"          android:text="DOMParser"          android:textSize="25sp"          android:textAllCaps="false"          android:layout_width="match_parent"          android:layout_height="wrap_content"/>      <Button          android:id="@+id/btn_pull"          android:text="PULLParser"          android:textSize="25sp"          android:textAllCaps="false"          android:layout_width="match_parent"          android:layout_height="wrap_content"/>        <TextView          android:id="@+id/tv_show"          android:textSize="25sp"          android:layout_width="match_parent"          android:layout_height="match_parent"/>  </LinearLayout></code></pre>    <h3><strong>开始定义实现IUserParser接口的解析类</strong></h3>    <p>方式一. SAX解析</p>    <pre>  <code class="language-java">package com.lyp.xml;    import org.xml.sax.Attributes;  import org.xml.sax.SAXException;  import org.xml.sax.helpers.DefaultHandler;    import java.io.InputStream;  import java.util.ArrayList;  import java.util.List;    import javax.xml.parsers.SAXParser;  import javax.xml.parsers.SAXParserFactory;    /**   * Created by ${思格斯} on 2016/9/22 0022.   */  public class UserSaxParser implements IUserParser {      @Override      public List<User> parse(InputStream is) throws Exception {          SAXParserFactory factory = SAXParserFactory.newInstance();  //取得SAXParserFactory实例          SAXParser parser = factory.newSAXParser();                  //从factory获取SAXParser实例          MyHandler handler = new MyHandler();                        //实例化自定义Handler          parser.parse(is, handler);                                  //根据自定义Handler规则解析输入流          return handler.getUsers();      }          //需要重写DefaultHandler的方法      private class MyHandler extends DefaultHandler {            private List<User> users;          private User user;          private StringBuilder builder;            //返回解析后得到的User对象集合          public List<User> getUsers() {              return users;          }            @Override          public void startDocument() throws SAXException {              super.startDocument();              users = new ArrayList<User>();              builder = new StringBuilder();          }            @Override          public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {              super.startElement(uri, localName, qName, attributes);              if (localName.equals("user")) {                  user = new User();              }              builder.setLength(0);   //将字符长度设置为0 以便重新开始读取元素内的字符节点          }            @Override          public void characters(char[] ch, int start, int length) throws SAXException {              super.characters(ch, start, length);              builder.append(ch, start, length);  //将读取的字符数组追加到builder中          }            @Override          public void endElement(String uri, String localName, String qName) throws SAXException {              super.endElement(uri, localName, qName);              if (localName.equals("id")) {                  user.setId(Long.parseLong(builder.toString()));              } else if (localName.equals("name")) {                  user.setName(builder.toString());              } else if (localName.equals("age")) {                  user.setAge(Integer.parseInt(builder.toString()));              } else if (localName.equals("sex")) {                  user.setSex(builder.toString());              } else if (localName.equals("user")) {                  users.add(user);              }          }      }  }</code></pre>    <p>方式二. DOM解析</p>    <pre>  <code class="language-java">package com.lyp.xml;    import org.w3c.dom.Document;  import org.w3c.dom.Element;  import org.w3c.dom.Node;  import org.w3c.dom.NodeList;    import java.io.InputStream;  import java.util.ArrayList;  import java.util.List;    import javax.xml.parsers.DocumentBuilder;  import javax.xml.parsers.DocumentBuilderFactory;    /**   * Created by ${思格斯} on 2016/9/22 0022.   */  public class UserDomParser implements IUserParser {        private List<User> mUsers;        @Override      public List<User> parse(InputStream is) throws Exception {          mUsers = new ArrayList<User>();          DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();//取得DocumentBuilderFactory实例          DocumentBuilder builder = factory.newDocumentBuilder();               //从factory获取DocumentBuilder实例          Document doc = builder.parse(is);                                     //解析输入流,得到Document实例            Element rootElement = doc.getDocumentElement();                       //获取根节点users          NodeList items = rootElement.getElementsByTagName("user");            //获取子节点user的集合          for (int i = 0; i < items.getLength(); i++) {              User user = new User();              Node item = items.item(i);                                        //获取各个user节点              NodeList properties = item.getChildNodes();                       //获取user节点下的各个子节点的集合              for (int j = 0; j < properties.getLength(); j++) {                  Node property = properties.item(j);                           //获取各个子节点                  String nodeName = property.getNodeName();                     //获取各个子节点的名字                  if (nodeName.equals("id")) {                      user.setId(Long.parseLong(property.getFirstChild().getNodeValue()));                  } else if (nodeName.equals("name")) {                      user.setName(property.getFirstChild().getNodeValue());                  } else if (nodeName.equals("age")) {                      user.setAge(Integer.parseInt(property.getFirstChild().getNodeValue()));                  } else if (nodeName.equals("sex")) {                      user.setSex(property.getFirstChild().getNodeValue());                  }              }              mUsers.add(user);          }          return mUsers;      }  }</code></pre>    <p>方式三. PULL解析</p>    <pre>  <code class="language-java">package com.lyp.xml;    import android.util.Xml;    import org.xmlpull.v1.XmlPullParser;    import java.io.InputStream;  import java.util.ArrayList;  import java.util.List;    /**   * Created by ${思格斯} on 2016/9/22 0022.   */  public class UserPullParser implements IUserParser{        @Override      public List<User> parse(InputStream is) throws Exception {          List<User> users = null;          User user = null;    //      XmlPullParserFactory factory = XmlPullParserFactory.newInstance();  //      XmlPullParser parser = factory.newPullParser();            XmlPullParser parser = Xml.newPullParser(); //由android.util.Xml创建一个XmlPullParser实例          parser.setInput(is, "UTF-8");               //设置输入流 并指明编码方式            int eventType = parser.getEventType();          while (eventType != XmlPullParser.END_DOCUMENT) {              switch (eventType) {                  case XmlPullParser.START_DOCUMENT:                      users = new ArrayList<User>();                      break;                  case XmlPullParser.START_TAG:                      if (parser.getName().equals("user")) {                          user = new User();                      } else if (parser.getName().equals("id")) {                          eventType = parser.next();                          if (user != null) {                              user.setId(Long.parseLong(parser.getText()));                          }                      } else if (parser.getName().equals("name")) {                          eventType = parser.next();                          if (user != null) {                              user.setName(parser.getText());                          }                      } else if (parser.getName().equals("age")) {                          eventType = parser.next();                          if (user != null) {                              user.setAge(Integer.parseInt(parser.getText()));                          }                      } else if (parser.getName().equals("sex")) {                          eventType = parser.next();                          if (user != null) {                              user.setSex(parser.getText());                          }                      }                      break;                  case XmlPullParser.END_TAG:                      if (parser.getName().equals("user")) {                          if (users != null) {                              users.add(user);                          }                          user = null;                      }                      break;              }              eventType = parser.next();          }          return users;      }  }</code></pre>    <h3><strong>MainActivty.java</strong></h3>    <pre>  <code class="language-java">package com.lyp.xml;    import android.content.res.XmlResourceParser;  import android.support.v7.app.AppCompatActivity;  import android.os.Bundle;  import android.view.View;  import android.widget.Button;  import android.widget.TextView;    import java.io.IOException;  import java.io.InputStream;  import java.util.List;    public class MainActivity extends AppCompatActivity implements View.OnClickListener{      private Button btnSax;      private Button btnDom;      private Button btnPull;        private TextView tvShow;        private List<User> userList;      private StringBuilder mBuilder;      @Override      protected void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          setContentView(R.layout.activity_main);            initView();          mBuilder=new StringBuilder();        }        private void initView() {          btnSax= (Button) findViewById(R.id.btn_sax);          btnDom= (Button) findViewById(R.id.btn_dom);          btnPull= (Button) findViewById(R.id.btn_pull);            tvShow= (TextView) findViewById(R.id.tv_show);            btnSax.setOnClickListener(this);          btnDom.setOnClickListener(this);          btnPull.setOnClickListener(this);      }        @Override      public void onClick(View v) {          switch (v.getId()){              //case R.id.btn_sax:              //case R.id.btn_dom:              case R.id.btn_pull:                  try {                      //获取assets目录下的xml文件输入流                      InputStream inputStream = getAssets().open("users.xml");                        //Sax解析                      //UserSaxParser saxParser = new UserSaxParser();                      //userList = saxParser.parse(inputStream);                        //Dom解析                      //UserDomParser domParser = new UserDomParser();                      //userList = domParser.parse(inputStream);                        //Pull解析                      UserPullParser pullParser = new UserPullParser();                      userList = pullParser.parse(inputStream);                        //将user集合中的数据读取出来                      for (int i=0;i<userList.size();i++){                          User user=userList.get(i);                          long id= user.getId();                          String name=user.getName();                          int age=user.getAge();                          String sex=user.getSex();                          mBuilder.append("id:"+id +" name:"+name +" age:"+age +" sex:"+sex +"\r\n");                      }                        //将数据显示到TextView                      tvShow.setText(mBuilder);                  } catch (IOException e) {                      e.printStackTrace();                  } catch (Exception e) {                      e.printStackTrace();                  }                  break;          }      }    }</code></pre>    <p> </p>    <p>来自:http://www.jianshu.com/p/00340117ff25</p>    <p> </p>