Android 之 使用DOM解析xml文件

[size=medium][color=darkred][b]DOM 解析 xml 格式的文件[/b][/color][/size]


[size=small][color=olive]1、 xml简介:xml实质是一个文本文件,能够用于存储数据,但应用程序却不能
直接的访问和操作。因此要操作xml文件,需要一个不仅能读懂xml文档而且能
提供相应的xml应用程序借口的xml解析器。


2、 常用的xml应用程序接口有两个:
a、DOM文档对象模型;核心:在内存中建立和xml文件相对应的树形结构数据。
b、SAX 简单应用程序接口:核心:事件处理机制。

3、 DOM的优缺点:
优点:一个应用程序可以方便的操作内存中树的节点来处理xml文档,获取自己需要的数据;

缺点:如果xml文档比较大,相应的document对象就要占用较多的内存空间;而且,应用程序可能不需要所有的数据,而只是部分的数据,为了部分数据却付出较大的空间代价。

4、 SAX 的优势:
SAX 不在内存中建立树形结构数据,占用内存空间较少,对于许多的应用程序,使用SAX解析器来获取xml数据效率较高;

5、 DOM 的核心:
DOM 的核心概念就是节点。DOM 在分析XML 文档时,将组成xml文档的各部分(元素、属性、文本、注释、处理指令等)映射为一个个对象,每个对象就叫节点。

6、 DOM 的本质是:节点的集合。

7、 常用的节点类型:文档、元素、属性;
不常用的节点类型:注释、处理指令、文档类型、CDATA段、文档片段、实体、实体引用、记号。

8、 DOM 节点类型:

文档节点:文档节点的根节点,也是文档中其它所有节点的父节点。注意:文档节点并不是xml文档的根元素,因为在xml文档中,处理指令、注释等内容可以出现在根元素之外,所有在构造DOM 树时,根元素并不适合作为根节点,于是就有了文档节点,而根元素则作为文档节点的子节点。在DOM API 中文档节点是通过org.w3c.dom.Document接口表示的。

元素节点:组成文档树的重要部分,表示了xml文档中的元素。通常元素拥有子元素、文本节点,或者两者的组合。元素节点也是唯一能够拥有属性的节点类型。在DOM API 中文档节点是通过org.w3c.com.Element接口表示的。

文本节点:只包含文本内容(在xml中成为字符串数据)的节点,可以油更多信息组成,也可以只包含空白。在文档树中,元素和属性的文本内容是由文本节点来表示的。通过 org.w3c.dom.Text 接口表示;

提示:文本节点可以只包含空白,因此如果元素的内容中包含空白,那么该元素节点的子节点中,也将包含空白组成的文本节点。

属性节点:代表了元素中的熟悉那个。文档中使用org.w3c.dom.Attr 接口表示的。因为属性实际上是附属于元素的,所有属性节点不能被看作是元素的子节点,因而在DOM 中属性没有被认为是文档树的一部分,在属性节点上调用getPatentNode() 、 getPreviousSibling() 和 getNextSibling() 返回的都是null。换句话说,属性节点其实是被看作包含它的元素节点的一部分,并不作为一个单独的节点在文档树中出现。

注释节点:表示注释内容, 使用 org.w3c.dom.Comment接口表示;

处理指令节点:表示xml文档中的处理指令。通过org.w3c.dom.ProcessingInstruction接口表示;

DocumentType节点:在DOM API 中文档类型节点都是通过org.w3c.dom.DocumentType接口表示的,每一个Document都有一个doctype属性,其值是null或者是DocumentType对象。

CADATA段节点:表示xml文档中的CDATA段; org.w3c.dom.CDATASection接口表示;

实体节点:表示一个在xml文档中已分析的或未分析的实体。 表示:... Entity

实体引用节点:被用于表示DOM树中的一个实体引用; 表示:... EntityReference

记号节点:表示了在DTD中声明的记号。 表示: ... Notation接口表示;


9、 DOM 对象接口:

DOM 的规范中,有四个基本的接口:Document , Node , NodeList , NamedNodeMap;

Document接口:对文档进行操作的入口,集成与Node接口。(Node接口是大多数接口的父类:Document/Element/Attribute/Text/Comment等接口);

NodeList 接口:节点的集合,通过该接口,可以建立节点名和节点之间的一一映射关系,从而利用节点名可以直接访问特定的节点;该接口提供了一个有序节点集合的抽象,使用:
Int getLength() 可以得到列表中节点的数目;
Node item(int index); 返回集合中执行索引的节点,从 0 开始;
提示:NodeList的对象是“Live”的,对文档的改变,会直接反映到相关的NodeList对象中;


10、 创建 DOM 解析器的步骤:
在JAXP(Java API for XML Parsing )DOM 解析器是DocumentBuilder类的一个实例。
第一步:创建DocumentBuilderFactory对象:
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

第二步:创建DocumentBuilder 对象:
DocumentBuilder builder = factory.newDocumentBuilder();

第三步:指定要解析的文件:
Document document = builder.parse(new File("xx.xml"));
[/color][/size]
11、 具体代码实现如下:

[size=medium][color=red][b] 案例一:利用DOM 创建xml文档[/b][/color][/size]
import java.io.File;
import java.io.FileOutputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.crimson.tree.XmlDocument;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Text;


/**
* DOM 解析器实际应用
* @author Administrator
*
*/
public class DOMTest {

/**
* 使用DOM 解析器创建xml文件
*/
public void domCreate() throws Exception{

// 1、 创建DocumentBuilderFactory对象
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

// 2、创建DocumentBuilder 对象解析器
DocumentBuilder parse = factory.newDocumentBuilder();

// 3、创建文档Document
Document doc = parse.newDocument(); // 创建文档节点

// 4、创建根元素
Element root = doc.createElement("students"); // 根元素节点

// 5、创建第一个子元素
Element stu1 = doc.createElement("student");
stu1.setAttribute("sno","11"); // 为student元素设置属性
Element name1 = doc.createElement("name");
Text name1value = doc.createTextNode("mike");
name1.appendChild(name1value);
stu1.appendChild(name1); // 将 name1 这个元素添加为 stu1 的子元素

Element age1 = doc.createElement("age");
Text age1value = doc.createTextNode("12");
age1.appendChild(age1value); // 将age1value 文本节点添加到 age 元素中
stu1.appendChild(age1); // age 添加为student的子元素

root.appendChild(stu1); // 将 student 添加为 students 的子元素

// 创建保存数据的文件
File file = new File("stu.xml"); // 默认路径,工程的根目录
FileOutputStream fos = new FileOutputStream(file); // 输出流,写文件

// import org.apache.crimson.tree.XmlDocument;
// jar包:crimson.jar
((XmlDocument)doc).write(fos); // 写文件
}

/**
* 利用 DOM 修改xml文档
*/
public void domUpdate() throws Exception{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder parse = factory.newDocumentBuilder();
Document doc = parse.parse("stu.xml");

// 增加一个子元素
Element stu3 = doc.createElement("student");
stu3.setAttribute("sno","111");
Element name3 = doc.createElement("name");
Text name3value = doc.createTextNode("tom");
name3.appendChild(name3value);
stu3.appendChild(name3);

// 年龄
Element age3 = doc.createElement("age"); // 创建 age 标记
Text age3value = doc.createTextNode("34");
age3.appendChild(age3value);
stu3.appendChild(age3);
Element root = doc.getDocumentElement();
root.appendChild(stu3);

// 重写写入修改的文件
File file = new File("stu1.xml");
FileOutputStream fos = new FileOutputStream(file);
((XmlDocument)doc).write(fos);
}




}



[size=small][color=red] 案例解析:[/color][/size]

import java.io.InputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import android.util.Log;

/**
* DOM 解析 XML 文档,得到具体的数据
*
* @author Administrator
*
*/
public class DOMParseService {

/**
* 对XML 文件进行解析,返回数据集合
*
* @param is
* 文档流( 需要被解析的资源 )
*/
public static void doParse(InputStream is) throws Exception {

// 1、创建DocumentBuilderFactory工厂对象
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

// 2、创建解析器 DocumentBuilder 对象
DocumentBuilder db = factory.newDocumentBuilder();

// 3、创建文档对象 , 根据文件流地址
Document document = db.parse(is);

// 4、获取文档的根元素节点 , root 节点
Element root = document.getDocumentElement();

// 5、获取根元素的子元素 , "元素标签为 stu 的子元素"
NodeList nodeList = root.getElementsByTagName("stu");

// 6、读取每一个子元素,获取对应的信息
for (int i = 0; i < nodeList.getLength(); i++) {
Element student = (Element) nodeList.item(i); // 得到一个子元素

/* 对应元素 ID 属性 */
String sno = student.getAttribute("sno");

NodeList child = student.getChildNodes(); // 获取所有孩子节点
Log.i("msg", "孩子节点数量:" + child.getLength());

for (int j = 0; j < child.getLength(); j++) {
if (child.item(j).getNodeType() == Node.ELEMENT_NODE) { // 如果为元素节点
if (child.item(j).getNodeName().equals("name")) { // 节点为name
// name 节点下为文本节点,获取值为获取第一个文本节点
String name = child.item(j).getFirstChild().getNodeValue();
} else if (child.item(j).getNodeName().equals("age")) {
String age = child.item(j).getFirstChild().getNodeValue();
}
}
//Log.i("msg", "第"+j+"个孩子节点为:"+child.item(j).getNodeName()+",值为:"+child.item(j).getFirstChild().getNodeValue());
}
}
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值