解析XML数据

1 原始数据

assets包下的 Book.xml文件



    
        1001
        Thinking In Java
        80.00
    

    
        1002
        Core Java
        90.00
    
    
        1003
        Hello, Andriod
        100.00
    
  

BookBean

public class Book {
  private int id;
  private String name;
  private float price;
  //get、set
  ...
}

2 定义解析接口

public interface BooksParser {
  /**
   * 解析输入流,得到Book对象集合--解析
   * 
   * @param is
   * @return
   * @throws Exception
   */
  List parse(InputStream is) throws Exception;

  /**
   * 序列化Book对象集合,得到XML形式的字符串--保存
   * 不用Parcelable是因为此时用于本地数据的保存,而不是用于内存的持久化
   * @param books
   * @return
   * @throws Exception
   */
   String serialize(List books) throws Exception;
}

3 编写解析类

1 DOM解析

package com.example.xml.parser;

import com.example.xml.model.Book;

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.io.StringWriter;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

/**
 * DOM 解析
 */
public class DomBookParser implements BooksParser {

  @Override
  public List parse(InputStream is) throws Exception {
    List books = new ArrayList();
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();// 获取DocumentBuilderFactory实例
    DocumentBuilder builder = factory.newDocumentBuilder();// 从factory获取DocumentBuilder实例
    Document doc = builder.parse(is);// 解析输入流,得到Document实例
    Element rootElement = doc.getDocumentElement();
    NodeList items = rootElement.getElementsByTagName("book");//所有Book节点

    for (int i = 0; i < items.getLength(); i++) {
      Book book = new Book();
      Node item = items.item(i);// 获取book节点集合(单个Book实例)
      NodeList properties = item.getChildNodes();// 获取子节点集合(各个属性)

      for (int j = 0; j < properties.getLength(); j++) {
        Node property = properties.item(j);
        String nodeName = property.getNodeName();
        if ("id".equals(nodeName)) {
          book.setId(Integer.parseInt(property.getFirstChild().getNodeValue()));
        } else if ("name".equals(nodeName)) {
          book.setName(property.getFirstChild().getNodeValue());
        } else if ("price".equals(nodeName)) {
          book.setPrice(Float.parseFloat(property.getFirstChild().getNodeValue()));
        }
      }
      books.add(book);
    }
    return books;
  }

  @Override
  public String serialize(List books) throws Exception {
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = factory.newDocumentBuilder();
    Document doc = builder.newDocument(); // 由builder创建新文档

    Element rootElement = doc.createElement("books");

    for (Book book : books) {
      Element bookElement = doc.createElement("book");
      bookElement.setAttribute("id", book.getId() + "");

      Element nameElement = doc.createElement("name");
      nameElement.setTextContent(book.getName());
      bookElement.appendChild(nameElement);

      Element priceElement = doc.createElement("price");
      priceElement.setTextContent(book.getPrice() + "");
      bookElement.appendChild(priceElement);

      rootElement.appendChild(bookElement);
    }

    doc.appendChild(rootElement);

    TransformerFactory transFactory = TransformerFactory.newInstance();// 取得TransformerFactory实例
    Transformer transformer = transFactory.newTransformer(); // 从transFactory获取Transformer实例
    transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); // 设置输出采用的编码方式
    transformer.setOutputProperty(OutputKeys.INDENT, "yes"); // 是否自动添加额外的空白
    transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); // 是否忽略XML声明

    StringWriter writer = new StringWriter();

    Source source = new DOMSource(doc); // 表明文档来源是doc
    Result result = new StreamResult(writer);// 表明目标结果为writer
    transformer.transform(source, result); // 开始转换

    return writer.toString();
  }

}

2 Pull解析

package com.example.xml.parser;

import java.io.InputStream;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlSerializer;

import android.util.Xml;
import com.example.xml.model.Book;
/**
 * Pull 解析
 * 轻巧灵活,速度快,占用内存小
 */
public class PullBookParser implements BooksParser {
  private List books = null;
  private Book book = null;

  @Override
  public List parse(InputStream is) throws Exception {
    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:
          books = new ArrayList();
          break;
        case XmlPullParser.START_TAG:
          if (parser.getName().equals("book")) {
            book = new Book();
          } else if (parser.getName().equals("id")) {
            eventType = parser.next();
            book.setId(Integer.parseInt(parser.getText()));
          } else if (parser.getName().equals("name")) {
            eventType = parser.next();
            book.setName(parser.getText());
          } else if (parser.getName().equals("price")) {
            eventType = parser.next();
            book.setPrice(Float.parseFloat(parser.getText()));
          }
          break;
        case XmlPullParser.END_TAG:
          if (parser.getName().equals("book")) {
            books.add(book);
            book = null;
          }
          break;
      }
      eventType = parser.next();
    }
    return books;
  }

  @Override
  public String serialize(List books) throws Exception {
    XmlSerializer serializer = Xml.newSerializer(); // 由android.util.Xml创建一个XmlSerializer实例
    StringWriter writer = new StringWriter();
    serializer.setOutput(writer); // 设置输出方向为writer
    serializer.startDocument("UTF-8", true);
    serializer.startTag("", "books");
    for (Book book : books) {
      serializer.startTag("", "book");
      serializer.attribute("", "id", book.getId() + "");

      serializer.startTag("", "name");
      serializer.text(book.getName());
      serializer.endTag("", "name");

      serializer.startTag("", "price");
      serializer.text(book.getPrice() + "");
      serializer.endTag("", "price");

      serializer.endTag("", "book");
    }
    serializer.endTag("", "books");
    serializer.endDocument();

    return writer.toString();
  }

}

3 SAX解析

package com.example.xml.parser;

import com.example.xml.model.Book;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
import org.xml.sax.helpers.DefaultHandler;

import java.io.InputStream;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;

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.TransformerFactory;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;

/**
 * SAX解析
 * @author Administrator
 *
 */
public class SaxBookParser implements BooksParser {

  @Override
  public List 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.getBooks();
  }

  @Override
  public String serialize(List books) throws Exception {
    SAXTransformerFactory factory = (SAXTransformerFactory) TransformerFactory.newInstance();// 取得SAXTransformerFactory实例
    TransformerHandler handler = factory.newTransformerHandler(); // 从factory获取TransformerHandler实例
    Transformer transformer = handler.getTransformer(); // 从handler获取Transformer实例
    transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); // 设置输出采用的编码方式
    transformer.setOutputProperty(OutputKeys.INDENT, "yes"); // 是否自动添加额外的空白
    transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); // 是否忽略XML声明

    StringWriter writer = new StringWriter();
    Result result = new StreamResult(writer);
    handler.setResult(result);

    String uri = ""; // 代表命名空间的URI 当URI无值时 须置为空字符串
    String localName = ""; // 命名空间的本地名称(不包含前缀) 当没有进行命名空间处理时 须置为空字符串

    handler.startDocument();
    handler.startElement(uri, localName, "books", null);

    AttributesImpl attrs = new AttributesImpl(); // 负责存放元素的属性信息
    char[] ch = null;
    for (Book book : books) {
      attrs.clear(); // 清空属性列表
      attrs.addAttribute(uri, localName, "id", "string", String.valueOf(book.getId()));// 添加一个名为id的属性(type影响不大,这里设为string)
      handler.startElement(uri, localName, "book", attrs); // 开始一个book元素 关联上面设定的id属性

      handler.startElement(uri, localName, "name", null); // 开始一个name元素 没有属性
      ch = String.valueOf(book.getName()).toCharArray();
      handler.characters(ch, 0, ch.length); // 设置name元素的文本节点
      handler.endElement(uri, localName, "name");

      handler.startElement(uri, localName, "price", null);// 开始一个price元素 没有属性
      ch = String.valueOf(book.getPrice()).toCharArray();
      handler.characters(ch, 0, ch.length); // 设置price元素的文本节点
      handler.endElement(uri, localName, "price");

      handler.endElement(uri, localName, "book");
    }
    handler.endElement(uri, localName, "books");
    handler.endDocument();

    return writer.toString();
  }

  // 需要重写DefaultHandler的方法
  private class MyHandler extends DefaultHandler {

    private List books;
    private Book book;
    private StringBuilder builder;

    // 返回解析后得到的Book对象集合
    public List getBooks() {
      return books;
    }

    @Override
    public void startDocument() throws SAXException {
      super.startDocument();
      books = new ArrayList();
      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("book")) {
        book = new Book();
      }
      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")) {
        book.setId(Integer.parseInt(builder.toString()));
      } else if (localName.equals("name")) {
        book.setName(builder.toString());
      } else if (localName.equals("price")) {
        book.setPrice(Float.parseFloat(builder.toString()));
      } else if (localName.equals("book")) {
        books.add(book);
      }
    }
  }
}

解析只要看第一个方法就行了。


4 解析类的使用

1 实例化解析类

DomBookParser parser=new DomBookParser();
//PullBookParser parser=new PullBookParser();
//SaxBookParser parser = new SaxBookParser();

2 解析xml文件

 InputStream is = getAssets().open("books.xml");
      books = parser.parse(is);
      for (Book book : books) {
        Log.i(TAG, book.toString());
      }

5 代码地址

http://download.csdn.net/detail/cherish20151011/9509352

你可能感兴趣的:(解析XML数据)