目前最常用的XML解析技术是DOM和SAX。
DOM是基于XML的树结构来完成解析的,适用于多次访问的XML文档,但是DOM解析比较消耗资源;而SAX是基于事件解析,适用于大数据量的XML文档,占用资源少,内存消耗小。
DOM是文档对象模型(Document Object Model)
首先DOM会将XML文档映射成一颗倒挂的树,在这棵树中,每个节点都是以节点对象的形式存在的。
我们通过操作这些对象就可以完成XML文件的读写任务了。
我们可以直接根据节点的名称或属性查找该节点对象,也可以根据一个节点查找其子节点或父节点的方式来寻找所需要的节点。然后对xml文档进行操作,使用这样的思路操作xml文件,我们称之为DOM解析。
使用DOM解析XML文档的步骤主要有:
1、创建解析器工厂。
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
2、由解析器工厂对象创建解析器对象。
DocumentBuilder db = dbf.newDocumentBuilder();
3、由解析器对象对指定xml文件进行解析。构建相应的DOM树,创建Document对象。
Document doc = db.parse("src/收藏信息.xml");
4、以Document对象为起点对DOM树的节点进行增删改查操作。
Document是个接口,他提供了对整个XML文档数据的基本访问。
常用方法 | 说明 |
NodeList getElementsByTagName(String tagName) | 按文档顺序返回文档中指定标记名称的所有元素集合 |
Element createElement(String tagName) | 创建指定标记名称的元素 |
操作XML的两个重要接口:Node和Element。
区别:Node表示文档树中的任意一种节点,可以是元素节点、属性节点或是文本节点等多种节点。Element则只表示Node节点中的元素节点。Node是Element的父接口。
Node
常用方法 | 说明 |
NodeList getChildNodes() | 获取该元素的所有子节点,返回为节点集合 |
常用方法 | 说明 |
String getTagName() | 元素名称 |
下面看一个具体的实例,了解DOM具体如何操作XML文档
首先新建一个名为收藏信息的xml文档,具体内容如下:
<PhoneInfo>
<Brand name="Apple">
<Type name="iPhone4"/>
<Type name="iPhone5"/>
</Brand>
<Brand name="华为">
<Type name="U8650"/>
</Brand>
</PhoneInfo>
然后看具体解析过程(包括对该XML文档的增删改查):
package com.pb.test;
import java.io.FileOutputStream;
import java.io.PrintWriter;
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.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.NodeList;
import com.pb.entity.Item;
public class Test {
public static void main(String[] args) {
//showItemByNum(1);
//savePhone();
//modify();
delete();
}
public static void delete(){
try {
// 1、得到DOM解析器的工厂实例
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// 2、从DOM工厂获得DOM解析器
DocumentBuilder db = dbf.newDocumentBuilder();
// 3、解析XML文档,得到一个Document,即DOM树
Document doc = db.parse("src/收藏信息.xml");
//找到删除的节点
NodeList list=doc.getElementsByTagName("Brand");
for(int i=0;i<list.getLength();i++){
Element brandElement=(Element)list.item(i);
String brandName=brandElement.getAttribute("name");
if(brandName.equals("联想")){
brandElement.getParentNode().removeChild(brandElement);
}
}
//保持XML文件
TransformerFactory transformerFactory = TransformerFactory
.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource domSource = new DOMSource(doc);
//设置编码类型
transformer.setOutputProperty(OutputKeys.ENCODING, "gb2312");
StreamResult result = new StreamResult(new FileOutputStream("src/收藏信息.xml"));
//把DOM树转换为XML文件
transformer.transform(domSource, result);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void modify(){
try {
// 1、得到DOM解析器的工厂实例
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// 2、从DOM工厂获得DOM解析器
DocumentBuilder db = dbf.newDocumentBuilder();
// 3、解析XML文档,得到一个Document,即DOM树
Document doc = db.parse("src/收藏信息.xml");
//找到修改的节点
NodeList list=doc.getElementsByTagName("Brand");
for(int i=0;i<list.getLength();i++){
Element brandElement=(Element)list.item(i);
String brandName=brandElement.getAttribute("name");
if(brandName.equals("苹果")){
//修改属性
brandElement.setAttribute("name", "Apple");
}
}
//保持XML文件
TransformerFactory transformerFactory = TransformerFactory
.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource domSource = new DOMSource(doc);
//设置编码类型
transformer.setOutputProperty(OutputKeys.ENCODING, "gb2312");
StreamResult result = new StreamResult(new FileOutputStream("src/收藏信息.xml"));
//把DOM树转换为XML文件
transformer.transform(domSource, result);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void savePhone() {
try {
// 1、得到DOM解析器的工厂实例
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// 2、从DOM工厂获得DOM解析器
DocumentBuilder db = dbf.newDocumentBuilder();
// 3、解析XML文档,得到一个Document,即DOM树
Document doc = db.parse("src/收藏信息.xml");
//创建brand节点
Element brandElement= doc.createElement("Brand");
brandElement.setAttribute("name", "华为");
//创建Type节点
Element typeElement=doc.createElement("Type");
typeElement.setAttribute("name", "U8650");
//添加父子关系
brandElement.appendChild(typeElement);
Element phoneElement=(Element)doc.getElementsByTagName("PhoneInfo").item(0);
phoneElement.appendChild(brandElement);
//保持XML文件
TransformerFactory transformerFactory = TransformerFactory
.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource domSource = new DOMSource(doc);
//设置编码类型
transformer.setOutputProperty(OutputKeys.ENCODING, "gb2312");
StreamResult result = new StreamResult(new FileOutputStream("src/收藏信息.xml"));
//把DOM树转换为XML文件
transformer.transform(domSource, result);
} catch (Exception e) {
e.printStackTrace();
}
}
public static List<Item> showItem() {
try {
// 1、得到DOM解析器的工厂实例
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// 2、从DOM工厂获得DOM解析器
DocumentBuilder db = dbf.newDocumentBuilder();
// 3、解析XML文档,得到一个Document,即DOM树
Document doc = db.parse("src/网易手机各地行情.xml");
// 4、读取新闻
NodeList list = doc.getElementsByTagName("item");
ArrayList<Item> itemList = new ArrayList<Item>();
for (int i = 0; i < list.getLength(); i++) {
Item item = new Item();
Element itemElement = (Element) list.item(i);
String title = itemElement.getElementsByTagName("title")
.item(0).getFirstChild().getNodeValue();
String description = itemElement.getElementsByTagName(
"description").item(0).getFirstChild().getNodeValue();
String link = itemElement.getElementsByTagName("link").item(0)
.getFirstChild().getNodeValue();
String pubDate = itemElement.getElementsByTagName("pubDate")
.item(0).getFirstChild().getNodeValue();
item.setDescription(description);
item.setLink(link);
item.setPubDate(pubDate);
item.setTitle(title);
itemList.add(item);
}
return itemList;
} catch (Exception ex) {
System.out.println(ex.getMessage());
return null;
}
}
public static void showItemByNum(int num) {
List<Item> listItem = showItem();
Item item = listItem.get(num - 1);
System.out.println(num + "\t" + item.getPubDate() + "\t"
+ item.getTitle());
}
}