Posted on 2009-12-20 14:07
啥都寫點 閱讀(347)
評論(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結構中的一個抽象的節(jié)點。

org.w3c.dom.NodeList:該對象代表了一個包含多個Node的列表。

org.w3c.dom.Element:該對象代表的是XML文檔中的標簽元素,繼承與Node.在標簽中可以包含屬性,因此Element對象中的存取其屬性的方法。

org.w3c.dom.Attr:該對象代表了某個標簽中的屬性。繼承于Node,但是因為Attr實際上是包含在Element中的,所以Attr并不是DOM樹的一部分。

通過DOM解析器工廠DocumentBuilderFactory的newDocumentBuilder方法可以創(chuàng)建一個DOM解析器對象,類型為DocumentBuilder,它的parse方法能夠將XML文檔讀取到內存,返回一個Document對象。

通過DocumentBuilder的newDocument方法創(chuàng)建一個新的XML文檔,返回一個Document對象。通過Document的appendChild方法往文檔中添加子節(jié)點。

使用JAXP(Java API for XML Processing)技術能將Document對象存儲到文件中。根據(jù)Document對象創(chuàng)建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對象,然后再來執(zhí)行后續(xù)的操作.
* node對象是dom結構中最為基本的對象,代表了文檔樹中的一個抽象的節(jié)點。在實際使用的時候,很少會真正的用到node這個對象,而是用到諸如element、attr、text等node對象的子對象來操作文檔。node對象為這些對象提供了一個抽象的、公共的根。雖然在node對象中定義了對其子節(jié)點進行存取的方法,但是有一些node子對象,比如text對象,它并不存在子節(jié)點,這一點是要注意的。
* 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樹中單獨的一個節(jié)點出現(xiàn)。這一點在使用的時候要同其它的node子對象相區(qū)別。
*/

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文檔的根節(jié)點“學生花名冊”
Element root = doc.getDocumentElement();
// 取"學生"元素列表
NodeList students = root.getElementsByTagName("學生");

for (int i = 0; i < students.getLength(); i++)
{
// 依次取每個"學生"元素
Element student = (Element) students.item(i);
// 創(chuàng)建一個學生的Bean實例
studentBean = new StudentBean();
// 取學生的性別屬性
studentBean.setGender(student.getAttribute("性別"));
// 取“姓名”元素
NodeList names = student.getElementsByTagName("姓名");

if (names.getLength() == 1)
{
Element e = (Element) names.item(0);
// 取姓名元素的第一個子節(jié)點,即為姓名的值節(jié)點
Text t = (Text) e.getFirstChild();
// 獲取值節(jié)點的值
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作準備,創(chuàng)建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
{
// 首先創(chuàng)建一個TransformerFactory對象,再由此創(chuàng)建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);
// 創(chuàng)建一個DOMSource對象,該構造函數(shù)的參數(shù)可以是一個Document對象
DOMSource source = new DOMSource(doc);
// 創(chuàng)建XSLT引擎的輸出對象,這里將輸出寫如文件
File file = new File(fileName);
StreamResult result = new StreamResult(file);
// 執(zhí)行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</電話>
</學生>
</學生花名冊>
--
學海無涯