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>