欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android编程实现XML解析与保存的三种方法详解

程序员文章站 2023-12-09 15:37:57
本文实例讲述了android编程实现xml解析与保存的三种方法。分享给大家供大家参考,具体如下: 简介 在android开发中,关于xml解析有三种方式,分别是: 1...

本文实例讲述了android编程实现xml解析与保存的三种方法。分享给大家供大家参考,具体如下:

简介

在android开发中,关于xml解析有三种方式,分别是:

1. sax 基于事件的解析器,解析速度快,占用内存少。非常适合在android移动设备中使用。
2. dom 在内存中以树形结构存放,因此检索和更新效率会更高。但是对于特别大的文档,解析和加载整个文档将会很耗资源
3. pull 基于事件的解析器,不同于sax是,pull是主动请求下一个事件,所以在可控上pull要比sax实用。android系统内部在解析各种xml时也是用pull解析器。

下面实现各种解析的类以及工程结构

Android编程实现XML解析与保存的三种方法详解

这是我们将要解析的xml文件id.xml以及其对应的book类

<?xml version="1.0" encoding="utf-8"?>
<books>
 <book id="1001">
  <name>thinking in java</name>
  <price>80.0</price>
 </book>
 <book id="1002">
  <name>core java</name>
  <price>90.0</price>
 </book>
 <book id="1003">
  <name>hello, andriod</name>
  <price>100.0</price>
 </book>
</books>

book.java

public class book {
  public static final string books = "books";
  public static final string book = "book";
  public static final string id = "id";
  public static final string name = "name";
  public static final string price = "price";
  private int id;
  private string name;
  private float price;
  public int getid() {
    return id;
  }
  public void setid(int id) {
    this.id = id;
  }
  public string getname() {
    return name;
  }
  public void setname(string name) {
    this.name = name;
  }
  public float getprice() {
    return price;
  }
  public void setprice(float price) {
    this.price = price;
  }
  @override
  public string tostring() {
    return "id:" + id + ",name:" + name + ",price:" + price;
  }
}

下面是xml解析类的实现

抽象类用于 xml文件读写的继承

xmlparsefactory.java

import java.io.inputstream;
import java.util.list;
public abstract class xmlparsefactory {
  /**
   * 读取指定的xml文件
   * @param inputstream xml文件输入流
   */
  public abstract void readxml(inputstream inputstream);
  /**
   * 保存xml到指定的文件
   * @param filepath 文件的绝对路径
   */
  public abstract void writexml(string filepath);
  /**
   * 获取book对象列表
   * @return
   */
  public abstract list<book> getbooklist();
  /**
   * 设置book对象列表
   */
  public abstract void setbooklist(list<book> booklist);
}

用sax实现的方法

saxparsertool.java

import java.io.filenotfoundexception;
import java.io.fileoutputstream;
import java.io.ioexception;
import java.io.inputstream;
import java.io.outputstreamwriter;
import java.util.arraylist;
import java.util.list;
import javax.xml.parsers.parserconfigurationexception;
import javax.xml.parsers.saxparser;
import javax.xml.parsers.saxparserfactory;
import javax.xml.transform.outputkeys;
import javax.xml.transform.result;
import javax.xml.transform.transformer;
import javax.xml.transform.transformerconfigurationexception;
import javax.xml.transform.transformerfactory;
import javax.xml.transform.sax.saxtransformerfactory;
import javax.xml.transform.sax.transformerhandler;
import javax.xml.transform.stream.streamresult;
import org.xml.sax.attributes;
import org.xml.sax.saxexception;
import org.xml.sax.helpers.attributesimpl;
import org.xml.sax.helpers.defaulthandler;
public class saxparsertool extends xmlparsefactory {
// private static final string tag = "saxparsertool";
  private saxhandler mhandler = new saxhandler();
  private list<book> mbooklist;
  @override
  public void readxml(inputstream inputstream) {
    try {
      saxparserfactory factory = saxparserfactory.newinstance();
      saxparser parser = factory.newsaxparser();
      parser.parse(inputstream, mhandler);
    } catch (parserconfigurationexception e) {
      e.printstacktrace();
    } catch (saxexception e) {
      e.printstacktrace();
    } catch (ioexception e) {
      e.printstacktrace();
    } finally {
      if (inputstream != null) {
        try {
          inputstream.close();
        } catch (ioexception e) {
          e.printstacktrace();
        }
      }
    }
  }
  @override
  public void writexml(string filepath) {
    saxtransformerfactory factory = (saxtransformerfactory) transformerfactory.newinstance();
    try {
      transformerhandler handler = factory.newtransformerhandler();
      transformer transformer = handler.gettransformer();
      transformer.setoutputproperty(outputkeys.encoding, "utf-8");
      transformer.setoutputproperty(outputkeys.indent, "yes");
      transformer.setoutputproperty(outputkeys.omit_xml_declaration, "no");
      fileoutputstream fos = new fileoutputstream(filepath);
      outputstreamwriter writer = new outputstreamwriter(fos);
      result result = new streamresult(writer);
      handler.setresult(result);
      string uri = "";
      string localname = "";
      handler.startdocument();
      handler.startelement(uri, localname, book.books, null);
      attributesimpl attrs = new attributesimpl();
      char[] ch = null;
      for (book book:mbooklist) {
        attrs.clear();
        attrs.addattribute(uri, localname, book.id, "string", string.valueof(book.getid()));
        handler.startelement(uri, localname, book.book, attrs);
        handler.startelement(uri, localname, book.name, null);
        ch = book.getname().tochararray();
        handler.characters(ch, 0, ch.length);
        handler.endelement(uri, localname, book.name);
        handler.startelement(uri, localname, book.price, null);
        ch = string.valueof(book.getprice()).tochararray();
        handler.characters(ch, 0, ch.length);
        handler.endelement(uri, localname, book.price);
        handler.endelement(uri, localname, book.book);
      }
      handler.endelement(uri, localname, book.books);
      handler.enddocument();
    } catch (transformerconfigurationexception e) {
      // todo auto-generated catch block
      e.printstacktrace();
    } catch (saxexception e) {
      // todo auto-generated catch block
      e.printstacktrace();
    } catch (filenotfoundexception e) {
      // todo auto-generated catch block
      e.printstacktrace();
    }
  }
  /**
   * 获取booklist列表
   * @return
   */
  public list<book> getbooklist() {
    if (mhandler == null) {
      return null;
    }
    return mhandler.getbooklist();
  }
  /**
   * 设置booklist列表
   * @param booklist
   */
  public void setbooklist(list<book> booklist) {
    mbooklist = booklist;
  }
  class saxhandler extends defaulthandler {
    private list<book> mbooklist;
    private book mbook;
    private string mtargetname;
    public list<book> getbooklist() {
      return mbooklist;
    }
    @override
    public void startdocument() throws saxexception {
      super.startdocument();
      mbooklist = new arraylist<book>();
    }
    @override
    public void enddocument() throws saxexception {
      super.enddocument();
    }
    @override
    public void startelement(string uri, string localname, string qname,
        attributes attributes) throws saxexception {
      super.startelement(uri, localname, qname, attributes);
      if (localname.equals(book.book)) {
        mbook = new book();
        mbook.setid(integer.valueof(attributes.getvalue(book.id)));
      }
      mtargetname = localname;
    }
    @override
    public void endelement(string uri, string localname, string qname)
        throws saxexception {
      super.endelement(uri, localname, qname);
      if (book.book.equals(localname)) {
        mbooklist.add(mbook);
      }
      mtargetname = null;
    }
    @override
    public void characters(char[] ch, int start, int length)
        throws saxexception {
      super.characters(ch, start, length);
      if (book.name.equals(mtargetname)) {
        mbook.setname(new string(ch, start, length));
      } else if (book.price.equals(mtargetname)) {
        mbook.setprice(float.valueof(new string(ch, start, length)));
      }
    }
  }
}

用pull实现的方法

pullparsertool.java

import java.io.filenotfoundexception;
import java.io.fileoutputstream;
import java.io.ioexception;
import java.io.inputstream;
import java.util.arraylist;
import java.util.list;
import org.xmlpull.v1.xmlpullparser;
import org.xmlpull.v1.xmlpullparserexception;
import org.xmlpull.v1.xmlserializer;
import android.util.xml;
public class pullparsertool extends xmlparsefactory {
// private static final string tag = "pullparsertool";
  private list<book> mbooklist;
  private book mbook;
  @override
  public void readxml(inputstream inputstream) {
    try {
      xmlpullparser parser = xml.newpullparser();
      parser.setinput(inputstream, "utf-8");
      int eventtype = parser.geteventtype();
      while (eventtype != xmlpullparser.end_document) {
        string name = parser.getname();
        switch (eventtype) {
        case xmlpullparser.start_document:
          mbooklist = new arraylist<book>();
          break;
        case xmlpullparser.start_tag:
//         log.d(tag, "getname:"+parser.getname()+","+parser.gettext());
          if (book.book.equals(name)) {
            mbook = new book();
            mbook.setid(integer.valueof(parser.getattributevalue("", book.id)));
          } else if (book.name.equals(name)) {
            mbook.setname(parser.nexttext());
          } else if (book.price.equals(name)) {
            mbook.setprice(float.valueof(parser.nexttext()));
          }
          break;
        case xmlpullparser.end_tag:
          if (book.book.equals(name)) {
            mbooklist.add(mbook);
          }
          break;
        default:
          break;
        }
        eventtype = parser.next();
      }
    } catch (xmlpullparserexception e) {
      e.printstacktrace();
    } catch (ioexception e) {
      e.printstacktrace();
    } finally {
      if (inputstream != null) {
        try {
          inputstream.close();
        } catch (ioexception e) {
          e.printstacktrace();
        }
      }
    }
  }
  @override
  public void writexml(string filepath) {
    xmlserializer serializer = xml.newserializer();
    fileoutputstream fos = null;
    try {
      fos = new fileoutputstream(filepath);
      serializer.setoutput(fos, "utf-8");
      serializer.startdocument("utf-8", true);
      serializer.starttag("", book.books);
      for (book book:mbooklist) {
        serializer.starttag("", book.book);
        serializer.attribute("", book.id, book.getid()+"");
        serializer.starttag("", book.name);
        serializer.text(book.getname());
        serializer.endtag("", book.name);
        serializer.starttag("", book.price);
        serializer.text(string.valueof(book.getprice()));
        serializer.endtag("", book.price);
        serializer.endtag("", book.book);
      }
      serializer.endtag("", book.books);
      serializer.enddocument();
    } catch (filenotfoundexception e) {
      e.printstacktrace();
    } catch (illegalargumentexception e) {
      e.printstacktrace();
    } catch (illegalstateexception e) {
      e.printstacktrace();
    } catch (ioexception e) {
      e.printstacktrace();
    } finally {
      if (fos != null) {
        try {
          fos.close();
        } catch (ioexception e) {
          e.printstacktrace();
        }
      }
    }
  }
  public list<book> getbooklist() {
    return mbooklist;
  }
  public void setbooklist(list<book> booklist) {
    mbooklist = booklist;
  }
}

用dom实现的方法

domparsertool.java

import java.io.filenotfoundexception;
import java.io.fileoutputstream;
import java.io.ioexception;
import java.io.inputstream;
import java.util.arraylist;
import java.util.list;
import javax.xml.parsers.documentbuilder;
import javax.xml.parsers.documentbuilderfactory;
import javax.xml.parsers.parserconfigurationexception;
import javax.xml.transform.outputkeys;
import javax.xml.transform.result;
import javax.xml.transform.source;
import javax.xml.transform.transformer;
import javax.xml.transform.transformerconfigurationexception;
import javax.xml.transform.transformerexception;
import javax.xml.transform.transformerfactory;
import javax.xml.transform.dom.domsource;
import javax.xml.transform.stream.streamresult;
import org.w3c.dom.document;
import org.w3c.dom.element;
import org.w3c.dom.node;
import org.w3c.dom.nodelist;
import org.xml.sax.saxexception;
import android.util.log;
public class domparsertool extends xmlparsefactory {
  private static final string tag = "domparsertool";
  private list<book> mbooklist;
  @override
  public void readxml(inputstream inputstream) {
    documentbuilderfactory factory = documentbuilderfactory.newinstance();
    try {
      documentbuilder builder = factory.newdocumentbuilder();
      document parse = builder.parse(inputstream);
      element root = parse.getdocumentelement();
      nodelist nodelist = root.getelementsbytagname(book.book);
      mbooklist = new arraylist<book>();
      log.d(tag,"length:"+nodelist.getlength());
      for (int i = 0; i < nodelist.getlength(); i++) {
        book book = new book();
        element item = (element) nodelist.item(i);
        book.setid(integer.valueof(item.getattribute(book.id)));
        nodelist nodes = item.getchildnodes();
        for (int j = 0; j < nodes.getlength(); j++) {
          node node = nodes.item(j);
          if (node.getnodetype() == node.element_node) {
            if (book.name.equals(node.getnodename())) {
              string content = node.gettextcontent();
              book.setname(content);
            } else if (book.price.equals(node.getnodename())) {
              string content = node.gettextcontent();
              book.setprice(float.valueof(content));
            }
          }
          log.d(tag, "readxml:"+node.getlocalname()+","+node.getnodename()
              +","+node.getnodetype()+","+node.getnodevalue()
              +","+node.gettextcontent()
              +","+node.tostring());
        }
        mbooklist.add(book);
      }
    } catch (parserconfigurationexception e) {
      e.printstacktrace();
    } catch (saxexception e) {
      e.printstacktrace();
    } catch (ioexception e) {
      e.printstacktrace();
    } finally {
      if (inputstream != null) {
        try {
          inputstream.close();
        } catch (ioexception e) {
          e.printstacktrace();
        }
      }
    }
  }
  @override
  public void writexml(string filepath) {
    documentbuilderfactory factory = documentbuilderfactory.newinstance();
    try {
      documentbuilder builder = factory.newdocumentbuilder();
      document document = builder.newdocument();
      element rootelement = document.createelement("books");
      for (book book:mbooklist) {
        element bookelement = document.createelement("book");
        bookelement.setattribute(book.id, book.getid()+"");
        element nameelement = document.createelement(book.name);
        nameelement.settextcontent(book.getname());
        bookelement.appendchild(nameelement);
        element priceelement = document.createelement(book.price);
        priceelement.settextcontent(string.valueof(book.getprice()));
        bookelement.appendchild(priceelement);
        rootelement.appendchild(bookelement);
      }
      document.appendchild(rootelement);
      transformerfactory transfactory = transformerfactory.newinstance();
      transformer transformer = transfactory.newtransformer();
      transformer.setoutputproperty(outputkeys.encoding, "utf-8");// 设置输出采用的编码方式
      transformer.setoutputproperty(outputkeys.indent, "yes");// 是否自动添加额外的空白
      transformer.setoutputproperty(outputkeys.omit_xml_declaration, "no");// 是否忽略xml声明
      fileoutputstream fos = new fileoutputstream(filepath);
      source source = new domsource(document);
      result result = new streamresult(fos);
      transformer.transform(source, result);
    } catch (parserconfigurationexception e) {
      e.printstacktrace();
    } catch (transformerconfigurationexception e) {
      e.printstacktrace();
    } catch (filenotfoundexception e) {
      e.printstacktrace();
    } catch (transformerexception e) {
      e.printstacktrace();
    }
  }
  public list<book> getbooklist() {
    return mbooklist;
  }
  public void setbooklist(list<book> booklist) {
    mbooklist = booklist;
  }
}

这是调用各种解析类的实现

mainactivity.java

import java.io.ioexception;
import java.io.inputstream;
import java.util.list;
import com.example.xmlparsedemo.xmlparser.book;
import com.example.xmlparsedemo.xmlparser.domparsertool;
import com.example.xmlparsedemo.xmlparser.pullparsertool;
import com.example.xmlparsedemo.xmlparser.saxparsertool;
import com.example.xmlparsedemo.xmlparser.xmlparsefactory;
import android.app.activity;
import android.os.bundle;
import android.os.environment;
import android.view.view;
import android.view.view.onclicklistener;
import android.widget.button;
import android.widget.textview;
public class mainactivity extends activity implements onclicklistener {
  private textview mtext;
  private xmlparsefactory parsefactory;
  @override
  protected void oncreate(bundle savedinstancestate) {
    super.oncreate(savedinstancestate);
    setcontentview(r.layout.activity_main);
    init();
  }
  private void init() {
    button saxreadbtn = (button) findviewbyid(r.id.id_saxread);
    button saxwritebtn = (button) findviewbyid(r.id.id_saxwrite);
    button domreadbtn = (button) findviewbyid(r.id.id_domread);
    button domwritebtn = (button) findviewbyid(r.id.id_domwrite);
    button pullreadbtn = (button) findviewbyid(r.id.id_pullread);
    button pullwritebtn = (button) findviewbyid(r.id.id_pullwrite);
    mtext = (textview) findviewbyid(r.id.id_text);
    saxreadbtn.setonclicklistener(this);
    saxwritebtn.setonclicklistener(this);
    domreadbtn.setonclicklistener(this);
    domwritebtn.setonclicklistener(this);
    pullreadbtn.setonclicklistener(this);
    pullwritebtn.setonclicklistener(this);
  }
  @override
  public void onclick(view v) {
    inputstream inputstream;
    try {
      inputstream = getassets().open("id.xml");
      switch (v.getid()) {
      case r.id.id_saxread:
        parsefactory = new saxparsertool();
        parsefactory.readxml(inputstream);
        showbooklist(parsefactory.getbooklist());
        break;
      case r.id.id_saxwrite:
        parsefactory.setbooklist(parsefactory.getbooklist());
        parsefactory.writexml(environment.getexternalstoragedirectory().getpath()+"/id.xml");
        break;
      case r.id.id_domread:
        parsefactory = new domparsertool();
        parsefactory.readxml(inputstream);
        showbooklist(parsefactory.getbooklist());
        break;
      case r.id.id_domwrite:
        parsefactory.writexml(environment.getexternalstoragedirectory().getpath()+"/id2.xml");
        break;
      case r.id.id_pullread:
        parsefactory = new pullparsertool();
        parsefactory.readxml(inputstream);
        showbooklist(parsefactory.getbooklist());
        break;
      case r.id.id_pullwrite:
        parsefactory.writexml(environment.getexternalstoragedirectory().getpath()+"/id3.xml");
        break;
      default:
        break;
      }
    } catch (ioexception e1) {
      e1.printstacktrace();
    }
  }
  private void showbooklist(list<book> booklist) {
    stringbuilder builder = new stringbuilder();
    for (book book:booklist) {
      builder.append(book.tostring());
      builder.append("\n");
    }
    mtext.settext(builder.tostring());
  }
}

解析实现的主布局

activity_main.xml

<scrollview xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent" >
  <linearlayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >
    <button
      android:id="@+id/id_saxread"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:text="saxparserread" />
    <button
      android:id="@+id/id_saxwrite"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:text="saxparserwrite" />
    <button
      android:id="@+id/id_domread"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:text="domparserread" />
    <button
      android:id="@+id/id_domwrite"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:text="domparserwrite" />
    <button
      android:id="@+id/id_pullread"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:text="pullparserread" />
    <button
      android:id="@+id/id_pullwrite"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:text="pullparserwrite" />
    <textview
      android:id="@+id/id_text"
      android:layout_width="match_parent"
      android:layout_height="wrap_content" />
  </linearlayout>
</scrollview>

效果图

Android编程实现XML解析与保存的三种方法详解

参考文章

ps:这里再为大家提供几款关于xml操作的在线工具供大家参考使用:

在线xml/json互相转换工具:

在线格式化xml/在线压缩xml

xml在线压缩/格式化工具:

xml代码在线格式化美化工具:

更多关于android相关内容感兴趣的读者可查看本站专题:《android操作xml数据技巧总结》、《android编程之activity操作技巧总结》、《android资源操作技巧汇总》、《android文件操作技巧汇总》、《android开发入门与进阶教程》、《android视图view技巧总结》及《android控件用法总结

希望本文所述对大家android程序设计有所帮助。