XML简单的数据存储语言

XML是eXtensible Markup Language的缩写,扩展标记语言XML
虽然XML占用的空间比二进制数据要占用更多的空间,但是XML极其简单易于掌握和使用
三种解析方法
1 DOM解析:
特点是先把dom全部文件读入到内存中,不适合大的XML数据
优点 她比较直观.
2 SAX是一种基于事件驱动的api有两部分:解析器和事件处理器,边读边解析.
3 PULL他也是边读边解析,它可以停止他主要是用next()方法来获取下一个解析时间getAttributte()方法来获取属性的值,也可以调用nextText()获取文本节点的值

代码

package com.example.wangye.androidxmlpasertest1609c;

import android.app.Activity;
import android.os.Bundle;
import android.support.constraint.solver.ArrayLinkedVariables;
import android.util.Xml;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
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 org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

public class MainActivity extends Activity {
Button btDOM,btPULL,btSAX;
  TextView tx;
  InputStream is;
  HashMap<String,String> map = null;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    init();
  }
  void init(){
    try {
      //读取assets目录中的文件  assets目录中的文件在打包APK的时候不会被编译成二进制
      is = getAssets().open("users.xml");
    } catch (Exception e) {
      e.printStackTrace();
    }
    btDOM = (Button) findViewById(R.id.button);
    btDOM.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
        tx.setText(domParse(is).toString());
      }
    });
    btPULL = (Button) findViewById(R.id.button2);
    btPULL.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
        tx.setText("当前解析:\n"+pullParse(is).toString());
      }
    });
    btSAX = (Button) findViewById(R.id.button3);
    btSAX.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
        tx.setText("SAX解析:\n"+saxParse(is).toString());
      }
    });
    tx = (TextView) findViewById(R.id.textView);
  }
   // DOM解析   把文件缓存至内存中   比较占内存  不适合大文件的读取
  ArrayList<HashMap<String,String>> domParse( InputStream is){
    ArrayList<HashMap<String,String>> alist= new ArrayList<HashMap<String,String>>();
    try {
      //创建解析对象工厂类
      DocumentBuilderFactory df = DocumentBuilderFactory.newInstance();
      //由工厂类对象创建解析对象
      DocumentBuilder db = df.newDocumentBuilder();
      //把需要读取的数据流或者文件  缓存至内存中Document中
      Document dt = db.parse(is);
      //获取Document中的所有节点信息
      Element root = dt.getDocumentElement();
      //获取有用节点信息
      NodeList fatherList = root.getElementsByTagName("person");
      for(int i = 0;i<fatherList.getLength();i++){
            //node节点不可以直接提取信息  需要转换成Element才可以提取信息
            Node node = fatherList.item(i);
           //强制转换成元素节点
            Element et = (Element) node;
        HashMap<String,String> map = new HashMap<String,String>();
        //获取person标签的属性值
        map.put("id",et.getAttribute("id"));
        //如果当前标签所携带的信息  是以子标签的形式的展示的  那么不可以直接提取   需要在分级
        NodeList childList = et.getChildNodes();
        //将父标签中子标签挨个循环读取
        for(int j = 0;j<childList.getLength();j++){
            Node childNode = childList.item(j);
          //判断当前读取的子标签是否是元素节点
          if(childNode.getNodeType() == Node.ELEMENT_NODE){
             //如果是  则可以直接提取信息
            if(childNode.getNodeName().equals("name")){
              map.put("name",childNode.getFirstChild().getNodeValue());
            }else if(childNode.getNodeName().equals("age")){
              map.put("age",childNode.getFirstChild().getNodeValue());
            }

          }
        }
        alist.add(map);
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
    return alist;
  }


  //PULL解析    采用事件驱动的方式(边读边解析)  pull解析可以在任意位置停止  适合大文件的解析
  ArrayList<HashMap<String,String>> pullParse( InputStream is){
    ArrayList<HashMap<String,String>> alist = new ArrayList<HashMap<String,String>>();
      //创建解析工具
    XmlPullParser pull = Xml.newPullParser();
    try {
      //参数2  编码格式
      pull.setInput(is,"UTF-8");
      //获取当前读取数据的节点类型  START_DUCUMENT  END_DOCUMENT START_TAG END_TAG
      int type = pull.getEventType();
      while(type != XmlPullParser.END_DOCUMENT){
        switch (type){
          case XmlPullParser.START_DOCUMENT://文档开始
            break;
          case XmlPullParser.START_TAG://标签开始
            if(pull.getName().equals("person")){
              map = new HashMap<String,String>();
              //根据位置获取节点里的属性信息
              map.put("id",pull.getAttributeValue(0));
            }
            //获取节点信息
            if(pull.getName().equals("name")){
              map.put("name",pull.nextText());
            }
            if(pull.getName().equals("age")){
              map.put("age",pull.nextText());
            }
            break;
          case XmlPullParser.END_TAG://标签结束
            if(pull.getName().equals("person")){
              alist.add(map);
            }
            break;
          case XmlPullParser.END_DOCUMENT://文档结束
            break;
        }
        //pull不会自动跳到下一个标签  手动指向下一个节点
//        if(){
//
//        }
        pull.next();
        type = pull.getEventType();
      }

    } catch (Exception e) {
      e.printStackTrace();
    }

    return alist;
  }

//SAX解析 跟PULL类似  采用的也是事件驱动的方式(边读边解析)  一旦解析停不下来
  ArrayList<HashMap<String,String>> saxParse( InputStream is){
    ArrayList<HashMap<String,String>> alist = new ArrayList<HashMap<String,String>>();
    try {
      //创建解析工厂类
      SAXParserFactory sf = SAXParserFactory.newInstance();
      //由工厂类创建解析对象
      SAXParser sp = sf.newSAXParser();
      //由解析对象使用解析工具进行解析
      //参数1  数据流  参数2  解析工具  需要单独创建工具类继承DefaultHandler
      SAXHandler handler = new SAXHandler();
      sp.parse(is,handler);
      alist = handler.alist;
    } catch (Exception e) {
      e.printStackTrace();
    }
       return alist;
  }

  class SAXHandler extends DefaultHandler{
    ArrayList<HashMap<String,String>> alist = new ArrayList<HashMap<String,String>>();
    HashMap<String,String> map = null;
    String tag;
    @Override//表示文档的开始   相当于PULL解析的 START_DOCUMENT
    public void startDocument() throws SAXException {
      super.startDocument();
    }

    @Override//表示文档的结束    相当于PULL解析的 END_DOCUMENT
    public void endDocument() throws SAXException {
      super.endDocument();
    }

    @Override//   获取开始标签   相当于PULL解析的 START_TAG
    //参数2  表示标签名称    参数4  获取属性信息
    // 属性信息的提取在这里获取   正文信息在characters方法里获取
    public void startElement(String uri, String localName, String qName, Attributes attributes)
        throws SAXException {
      if(localName.equals("person")){
        map = new HashMap<String,String>();
        map.put("id",attributes.getValue(0));
      }
      tag = localName;
    }

    @Override//   获取结束标签   相当于PULL解析的 END_TAG\
    //在结束标签里   把开始标签中获取的标签名清空  否则获取不到数据
    public void endElement(String uri, String localName, String qName) throws SAXException {
      if(localName.equals("person")){
        alist.add(map);
        map = null;
      }
      tag = null;
    }

    @Override//获取开始标签之后的标签文本    不是属性信息
    public void characters(char[] ch, int start, int length) throws SAXException {
//      byte b[] = new byte[3];
//      try {
//        String s = new String(b,"utf-8");
//      } catch (UnsupportedEncodingException e) {
//        e.printStackTrace();
//      }
//      Math.random();//[0,1)
      String data = new String(ch,start,length);
      if(map!=null){
        if("name".equals(tag)){
          map.put("name",data);
        }
        if("age".equals(tag)){
          map.put("age",data);
        }
      }

    }
  }
}

解析的XML文件

<?xml version="1.0" encoding="UTF-8"?>
<persons>
    <person id="23">
        <name>李雷</name>
        <age>30</age>
    </person>
    <person id="20">
        <name>韩梅梅</name>
        <age>25</age>
    </person>
</persons>
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容