DOM解析器:

DOM是基于树形结构的的节点或信息片段的集合,允许开发人员使用DOM API遍历XML树、检索所需数据。分析该结构通常需要加载整个文档和构造树形结构,然后才可以检索和更新节点信息。Android完全支持DOM 解析。利用DOM中的对象,可以对XML文档进行读取、搜索、修改、添加和删除等操作。

DOM工作原理:

使用DOM对XML文件进行操作时,首先要解析文件,将文件分为独立的元素、属性和注释等,然后以节点树的形式在内存中对XML文件进行表示,就可以通过节点树访问文档的内容,并根据需要修改文档——这就是DOM的工作原理。

DOM解析器优点:

1、可以对XML文档进行读取、搜索、修改、添加和删除等操作

2、由于DOM在内存中以树形结构存放,因此检索和更新效率会更高

DOM解析器缺点:

1、但是对于特别大的文档,解析和加载整个文档将会很耗资源

常用的DoM接口和类:

Document:该接口定义分析并创建DOM文档的一系列方法,它是文档树的根,是操作DOM的基础。

Element:该接口继承Node接口,提供了获取、修改XML元素名字和属性的方法。

Node:该接口提供处理并获取节点和子节点值的方法。

NodeList:提供获得节点个数和当前节点的方法。这样就可以迭代地访问各个节点。

DOMParser:该类是Apache的Xerces中的DOM解析器类,可直接解析XML文件。

DOM操作步骤:

1、首先利用DocumentBuilderFactory创建一个DocumentBuilderFactory实例
2、然后利用DocumentBuilderFactory创建DocumentBuilder

3、然后加载XML文档(Document,
4、然后获取文档的根结点(Element)
5、然后获取根结点中所有子节点的列表(NodeList),
6、然后使用再获取子节点列表中的需要读取的结点。

注意:这里的books.xml、Book.java和自定义解析器接口BookParser.java与上篇 Android 创建与解析XML(一)---- SAX方式 中的是一样的

DOM解析器代码:

DomBookParser.java

package com.sym.xml;

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.Transformer;
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 android.util.Log;

public class DomBookParser implements BookParser {

@Override
public List<Book> parser(InputStream is) throws Exception {
List<Book> books = new ArrayList<Book>();
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");
Log.e("NodeList.getLength", "----"+items.getLength());
for(int i=0; i<items.getLength(); i++){
Book book = new Book();
Node item = items.item(i);
NodeList properties = item.getChildNodes();
Log.e("properties.getLength", "----"+properties.getLength());
for(int j=0; j<properties.getLength(); j++){
Node property = properties.item(j);
String nodeName = property.getNodeName();
Log.e("nodeName", "----"+nodeName);
if(nodeName.equals("id")){
book.setId(Integer.parseInt(property.getFirstChild().getNodeValue()));
}else if(nodeName.equals("name")){
book.setName(property.getFirstChild().getNodeValue());
}else if(nodeName.equals("price")){
Log.e("price----", ""+property.getFirstChild().getNodeValue());
book.setPrice(Float.parseFloat(property.getFirstChild().getNodeValue()));
}
}
books.add(book);
}
return books;
}

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

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");
Node nodeName = doc.createTextNode(book.getName());
nameElement.appendChild(nodeName);
bookElement.appendChild(nameElement);
Log.e("book.getName()", "----"+book.getName());

Element priceElement = doc.createElement("price");
Node nodePrice = doc.createTextNode(book.getPrice()+"");
priceElement.appendChild(nodePrice);
bookElement.appendChild(priceElement);
Log.e("book.getPrice()", "----"+book.getPrice());

rootElement.appendChild(bookElement);
}
doc.appendChild(rootElement);

StringWriter writer = new StringWriter();
DOMSource source = new DOMSource(doc.getDocumentElement());//表明文档来源是doc
Result result = new StreamResult(writer);//表明目标结果为writer
transformer.transform(source, result);//开始转换
Log.e("source----", "" + writer.toString());
return writer.toString();
}

}
布局文件的XML代码与上篇一样

MainActivity.java只要修改一个地方---在read方法中将实例化的是DomBookParser对象就可以了。

public void read(View v){
try {
InputStream is = getAssets().open("books.xml");
//parser = new SaxBookParser();//创建SaxBookParser实例
parser = new DomBookParser();
//parser = new PullBookParser();
books = parser.parser(is);//解析输入流
StringBuffer sb = new StringBuffer();
sb.append("解析XML结果:" + "\n");
for(Book book : books){
sb.append(book.toString() + "\n");
Log.i(TAG, book.toString());
}
readxml.setText(sb.toString());
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}

}

执行的结果图:

更多相关文章

  1. android权限申请库解析
  2. android代码混淆压缩、资源压缩全解析
  3. Android(安卓)Binder 全解析(1) -- 概述
  4. 关于在使用gson解析json时建模与规范冲突的问题
  5. Android(安卓)JSON解析库Gson和Fast-json的使用对比和图书列表小
  6. 偷师阿里内部,月入20k程序员的Android规范文档
  7. 解析Android数据加密之异或加密算法
  8. Android(安卓)XML解析学习——方式比较
  9. Android事件分发机制源码畅游解析(Activity篇)

随机推荐

  1. c语言怎么用scanf输入字符串
  2. 如何用c语言输出100到200之间的素数
  3. vb和c语言有什么区别
  4. c++中string的用法介绍
  5. xcode怎么用
  6. c编译程序的功能是什么
  7. 主函数在程序中的位置在哪
  8. 指针和引用的不同点与相同点分别是什么
  9. c语言函数如何声明
  10. 程序中的注释部分是否参加编译?