Posted on 2009-12-20 14:07
啥都写点 阅读(341)
评论(0) 编辑 收藏 所属分类:
J2SE
DOM(Document Object Model)是一种处理XML文档的技术,通过DOM能够读取、修改XML文档。本例将介绍用DOM处理XML文档,把一个描述学生信息的XML文档读到内存中,构成多个学生对象,然后把这些学生对象的信息保存到另一个XML文档中。
DOM将整个XML文档读到内存中,用基本对象描述XML文档的元素,基本对象之间以树形的结构组织。
DOM常用的基本对象类有5个:
org.w3c.dom.Document:该类的对象代表了整个XML的文档,所有其他的XML元素,都以一定的顺序包含在Document对象内,排列成一个树形结构,可以通过遍历这棵树来得到XML文档的所有内容,这也是对XML文档操作的起点。
org.w3c.dom.Node:该类是一个接口类,定义了DOM结构中的一个抽象的节点。
org.w3c.dom.NodeList:该对象代表了一个包含多个Node的列表。
org.w3c.dom.Element:该对象代表的是XML文档中的标签元素,继承与Node.在标签中可以包含属性,因此Element对象中的存取其属性的方法。
org.w3c.dom.Attr:该对象代表了某个标签中的属性。继承于Node,但是因为Attr实际上是包含在Element中的,所以Attr并不是DOM树的一部分。
通过DOM解析器工厂DocumentBuilderFactory的newDocumentBuilder方法可以创建一个DOM解析器对象,类型为DocumentBuilder,它的parse方法能够将XML文档读取到内存,返回一个Document对象。
通过DocumentBuilder的newDocument方法创建一个新的XML文档,返回一个Document对象。通过Document的appendChild方法往文档中添加子节点。
使用JAXP(Java API for XML Processing)技术能将Document对象存储到文件中。根据Document对象创建DOMSource,使用Transformer的transform方法将DOMSource转换成XML文档。
/** *//**-------------------------------------StudentBean.java-----------------------------------------------*/
/** *//**
* 描述学生的JavaBean
*/
public class StudentBean {
// 学生姓名
private String name;
// 学生性别
private String gender;
// 学生年龄
private int age;
// 学生电话号码
private String phone;
public String toString(){
StringBuffer sb = new StringBuffer();
sb.append("姓名:").append(this.name).append("; ");
sb.append("性别:").append(gender).append("; ");
sb.append("年龄:").append(age).append("; ");
sb.append("电话:").append(phone);
return sb.toString();
}
/** *//**
* @return 返回 age。
*/
public int getAge() {
return age;
}
/** *//**
* @param age 要设置的 age。
*/
public void setAge(int age) {
this.age = age;
}
/** *//**
* @return 返回 gender。
*/
public String getGender() {
return gender;
}
/** *//**
* @param gender 要设置的 gender。
*/
public void setGender(String gender) {
this.gender = gender;
}
/** *//**
* @return 返回 name。
*/
public String getName() {
return name;
}
/** *//**
* @param name 要设置的 name。
*/
public void setName(String name) {
this.name = name;
}
/** *//**
* @return 返回 phone。
*/
public String getPhone() {
return phone;
}
/** *//**
* @param phone 要设置的 phone。
*/
public void setPhone(String phone) {
this.phone = phone;
}
}
/** *//**----------------------------------DomXML.java------------------------------------*/
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
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.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
/** *//**
* dom的基本对象有5个:document,node,nodelist,element和attr
* document对象代表了整个xml的文档,所有其它的node,都以一定的顺序包含在document对象之内,排列成一个树形的结构,程序员可以通过遍历这颗树来得到xml文档的所有的内容,这也是对xml文档操作的起点。我们总是先通过解析xml源文件而得到一个document对象,然后再来执行后续的操作.
* node对象是dom结构中最为基本的对象,代表了文档树中的一个抽象的节点。在实际使用的时候,很少会真正的用到node这个对象,而是用到诸如element、attr、text等node对象的子对象来操作文档。node对象为这些对象提供了一个抽象的、公共的根。虽然在node对象中定义了对其子节点进行存取的方法,但是有一些node子对象,比如text对象,它并不存在子节点,这一点是要注意的。
* nodelist对象,顾名思义,就是代表了一个包含了一个或者多个node的列表.
* element对象代表的是xml文档中的标签元素,继承于node,亦是node的最主要的子对象。在标签中可以包含有属性,因而element对象中有存取其属性的方法,而任何node中定义的方法,也可以用在element对象上面。
* attr对象代表了某个标签中的属性。attr继承于node,但是因为attr实际上是包含在element中的,它并不能被看作是element的子对象,因而在dom中attr并不是dom树的一部分,所以node中的getparentnode(),getprevioussibling()和getnextsibling()返回的都将是null。也就是说,attr其实是被看作包含它的element对象的一部分,它并不作为dom树中单独的一个节点出现。这一点在使用的时候要同其它的node子对象相区别。
*/
public class DomXML {
public static List readXMLFile(String inFile) throws Exception {
// 得到DOM解析器的工厂实例
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = null;
try {
// 从DOM工厂获得DOM解析器
db = dbf.newDocumentBuilder();
} catch (ParserConfigurationException pce) {
System.err.println(pce);
return null;
}
Document doc = null;
try {
// 解析XML文档的输入流,得到一个Document
doc = db.parse(inFile);
// 对document对象调用normalize(),可以去掉xml文档中作为格式化内容的空白,
// 避免了这些空白映射在dom树中成为不必要的text node对象。
// 否则你得到的dom树可能并不是你所想象的那样。
// 特别是在输出的时候,这个normalize()更为有用。
doc.normalize();
} catch (DOMException dom) {
System.err.println(dom.getMessage());
return null;
} catch (IOException ioe) {
System.err.println(ioe);
return null;
}
List studentBeans = new ArrayList();
StudentBean studentBean = null;
// 得到XML文档的根节点“学生花名册”
Element root = doc.getDocumentElement();
// 取"学生"元素列表
NodeList students = root.getElementsByTagName("学生");
for (int i = 0; i < students.getLength(); i++) {
// 依次取每个"学生"元素
Element student = (Element) students.item(i);
// 创建一个学生的Bean实例
studentBean = new StudentBean();
// 取学生的性别属性
studentBean.setGender(student.getAttribute("性别"));
// 取“姓名”元素
NodeList names = student.getElementsByTagName("姓名");
if (names.getLength() == 1) {
Element e = (Element) names.item(0);
// 取姓名元素的第一个子节点,即为姓名的值节点
Text t = (Text) e.getFirstChild();
// 获取值节点的值
studentBean.setName(t.getNodeValue());
}
// 取“年龄”元素
NodeList ages = student.getElementsByTagName("年龄");
if (ages.getLength() == 1) {
Element e = (Element) ages.item(0);
Text t = (Text) e.getFirstChild();
studentBean.setAge(Integer.parseInt(t.getNodeValue()));
}
// 取“电话”元素
NodeList phones = student.getElementsByTagName("电话");
if (phones.getLength() == 1) {
Element e = (Element) phones.item(0);
Text t = (Text) e.getFirstChild();
studentBean.setPhone(t.getNodeValue());
}
// 将新建的Bean加到结果列表中
studentBeans.add(studentBean);
}
// 返回结果列表
return studentBeans;
}
/** *//**
* 用DOM写XML文档,把学生信息以XML文档的形式存储
* @param outFile 输出XML文档的路径
* @param studentGeans 学生信息
* @throws Exception
*/
public static String writeXMLFile(String outFile, List studentGeans) throws Exception {
//为解析XML作准备,创建DocumentBuilderFactory实例,指定DocumentBuilder
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = null;
try {
db = dbf.newDocumentBuilder();
} catch (ParserConfigurationException pce) {
System.err.println(pce);
return null;
}
// 新建一个空文档
Document doc = null;
doc = db.newDocument();
// 下面是建立XML文档内容的过程.
// 先建立根元素"学生花名册",并添加到文档中
Element root = doc.createElement("学生花名册");
doc.appendChild(root);
//取学生信息的Bean列表
for (int i = 0; i < studentGeans.size(); i++) {
// 依次取每个学生的信息
StudentBean studentBean = (StudentBean) studentGeans.get(i);
// 建立“学生”元素,有一个“性别”属性,然后添加到根元素
Element student = doc.createElement("学生");
student.setAttribute("性别", studentBean.getGender());
root.appendChild(student);
// 建立"姓名"元素,添加到学生下面
Element name = doc.createElement("姓名");
student.appendChild(name);
// 为“姓名”元素赋值
Text tName = doc.createTextNode(studentBean.getName());
name.appendChild(tName);
// 建立“年龄”元素,然后给元素赋值
Element age = doc.createElement("年龄");
student.appendChild(age);
Text tAge = doc .createTextNode(
String.valueOf(studentBean.getAge()));
age.appendChild(tAge);
// 建立“电话”元素,然后给元素赋值
Element phone = doc.createElement("电话");
student.appendChild(phone);
Text tPhone = doc.createTextNode(studentBean.getPhone());
phone.appendChild(tPhone);
}
// 把XML文档输出到指定的文件
return domDocToFile(doc, outFile, "GB2312");
}
/** *//**
* 使用JAXP将DOM对象写到XML文档里
* @param doc DOM的文档对象
* @param fileName 写入的XML文档路径
* @param encoding XML文档的编码
* @throws TransformerException
*/
public static String domDocToFile(Document doc, String fileName, String encoding)
throws TransformerException {
// 首先创建一个TransformerFactory对象,再由此创建Transformer对象。
// Transformer类相当于一个XSLT引擎。通常我们使用它来处理XSL文件,
// 但是在这里我们使用它来输出XML文档。
TransformerFactory tFactory = TransformerFactory.newInstance();
Transformer transformer = tFactory.newTransformer();
// 获取Transformser对象的输出属性,亦即XSLT引擎的缺省输出属性,是java.util.Properties对象
Properties properties = transformer.getOutputProperties();
// 设置新的输出属性:输出字符编码为GB2312,这样可以支持中文字符,
// XSLT引擎所输出的XML文档如果包含了中文字符,可以正常显示。
properties.setProperty(OutputKeys.ENCODING, "GB2312");
// 这里设置输出为XML格式,实际上这是XSLT引擎的默认输出格式
properties.setProperty(OutputKeys.METHOD, "xml");
transformer.setOutputProperties(properties);
// 创建一个DOMSource对象,该构造函数的参数可以是一个Document对象
DOMSource source = new DOMSource(doc);
// 创建XSLT引擎的输出对象,这里将输出写如文件
File file = new File(fileName);
StreamResult result = new StreamResult(file);
// 执行DOM文档到XML文件的转换
transformer.transform(source, result);
// 将输出文件的路径返回
return file.getAbsolutePath();
}
public static void main(String[] args) {
String inFileName = "students.xml";
String outFileName = "students_new.xml";
try {
List studentBeans = DomXML.readXMLFile(inFileName);
DomXML.writeXMLFile(outFileName, studentBeans);
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**----------------------------------文件名:studnet.xml------------------------------------*/
<?xml version="1.0" encoding="GB2312"?>
<学生花名册>
<学生 性别 = "男">
<姓名>张三</姓名>
<年龄>145</年龄>
<电话>62875555</电话>
</学生>
<学生 性别 = "女">
<姓名>李四</姓名>
<年龄>16</年龄>
<电话>82734254</电话>
</学生>
</学生花名册>
用DOM生成的student_new.xml文件的内容如下:
/**----------------------------------文件名:studnet_new.xml------------------------------------*/
<?xml version="1.0" encoding="GB2312"?>
<学生花名册>
<学生 性别 = "男">
<姓名>张三</姓名>
<年龄>145</年龄>
<电话>62875555</电话>
</学生>
<学生 性别 = "女">
<姓名>李四</姓名>
<年龄>16</年龄>
<电话>82734254</电话>
</学生>
</学生花名册>
-- 学海无涯