分类: Java
2009-05-31 09:34:54
声明:本Base Class在GUN GPL协议授权下发行,使用本Base Class请保留版权信息。
JDOM是一个开源项目,它基于树型结构,利用纯Java的技术对XML文档实现解析、生成、序列化以及多种操作。利用JDOM处理XML文档将是一件轻松、简单的事。JDOM 在2000年的春天被Brett McLaughlin和Jason Hunter开发出来,以弥补DOM及SAX在实际应用当中的不足之处。这些不足之处主要在于SAX没有文档修改、随机访问以及输出的功能,而对于DOM来说,JAVA程序员在使用时来用起来总觉得不太方便。在2002年的JavaOne会议上JDOM的主要创始人Jason Hunter有一篇精彩的演讲介绍了JDOM技术,题目就是JDOM Makes XML Easy。JDOM 直接为JAVA编程服务,它利用更为强有力的JAVA语言的诸多特性(方法重载、集合概念以及映射),把SAX和DOM的功能有效地结合起来。在使用设计上尽可能地隐藏原来使用XML过程中的复杂性。DOM的缺点主要是来自于由于Dom是一个接口定义语言(IDL),它的任务是在不同语言实现中的一个最低的通用标准,并不是为JAVA特别设计的。最近JDOM被收录到JSR-102内,这标志着JDOM成为了JAVA平台组成的一部分。
在我写的这个Base Class中,可以实现创建Document对象,初始化Element对象,对Element对象进行有条件的修改、查找操作,对Document对象进行添加、删除节点操作,读取、保存XML文件的操作。这个Base Class是完全通过JDOM来实现操作XML文件,并对XML文件中的特殊字符进行了过滤,防止出现无效的XML文件。
1. Base Class代码/*
* Copyright © 2008 Nervous Organization, All rights reserved.
*
* LICENSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License (GPL)
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* To read the license please visit [url][/url]
*
*/
package org.agricultureonline.common.util;
import java.io.File;
import java.io.FileWriter;
import java.util.List;
import org.jdom.*;
import org.jdom.input.SAXBuilder;
import org.jdom.output.*;
/**
* @author Steven Wee
* @version $Revision: 1.0 $ $Date: 2008/12/05 23:07:00 $
*/
public class BaseXMLOperator {
/**
* 生成一个新的Document对象
* @return document
*/
protected Document createDocument() {
Document document = new Document();
return document;
}
/**
* 创建一个新的Element对象
* @param paramName Element对象名称
* @param paramValue Element对象值
* @return element
*/
protected Element createElement( String paramName, String paramValue) {
// 初始化Element
Element element = new Element(paramName);
// 设置Element的值,格式化一遍字符串
element.setText(formatTextForXML(paramValue));
return element;
}
/**
* 向XML文件中增加节点
* @param document 载入XML文件后获得的Document对象
* @param fatherElementId 要增加节点的父节点Id
* @param element 要增加的节点对象
* @return true-增加节点成功 false-增加节点失败
*/
protected boolean addElement( Document document, String fatherElementId, Element element ) {
if ( document == null || fatherElementId == null || element == null ) {
return false;
}
// 得到根元素
Element rootElement = document.getRootElement().getChild(fatherElementId);
if ( rootElement == null ) {
return false;
}
rootElement.addContent(element);
return true;
}
/**
* 修改节点的属性值
* @param element 要修改的节点对象
* @param paramName 要修改的属性名称
* @param paramValue 要修改的属性值
* @return true-修改成功 false-修改失败
*/
protected boolean editElement( Element element, String paramName, String paramValue) {
if ( element == null || paramName == null || paramValue == null ) {
return false;
}
Element editElement = element.getChild(paramName);
if ( editElement == null ) {
return false;
}
editElement.setText(formatTextForXML(paramValue));
return true;
}
/**
* 修改节点的属性值
* @param document 载入XML文件后获得的Document对象
* @param fatherElementId 父节点Id
* @param elementId 节点Id
* @param Id 要删除的节点标示
* @param paramName 要修改的属性名称
* @param paramValue 要修改的属性值
* @return true-修改成功 false-修改失败
*/
protected boolean editElement( Document document, String fatherElementId, String elementId, String Id, String paramName, String paramValue) {
return editElement(findElement(document, fatherElementId, elementId, Id), paramName, paramValue);
}
/**
* 从XML文件中删除节点
* @param document 载入XML文件后获得的Document对象
* @param fatherElementId 要删除节点的父节点Id
* @param element 要删除的节点对象
* @return true-删除节点成功 false-删除节点失败
*/
protected boolean delElement( Document document, String fatherElementId, Element element ) {
// 得到根元素
Element rootElement = document.getRootElement().getChild(fatherElementId);
// 删除节点
if ( rootElement.removeContent(element) ) {
// 删除成功
return true;
}
// 删除失败
return false;
}
/**
* 从XML文件中删除节点
* @param document 载入XML文件后获得的Document对象
* @param fatherElementId 父节点Id
* @param elementId 节点Id
* @param Id 要删除的节点标示
* @return true-删除节点成功 false-删除节点失败
*/
protected boolean delElement( Document document, String fatherElementId, String elementId, String Id ) {
return delElement( document, fatherElementId, findElement(document, fatherElementId, elementId, Id));
}
/**
* 遍历Document对象中的所有节点,查找符合用户提供的节点对象
* @param document 载入XML文件后获得的Document对象
* @param fatherElementId 父节点Id
* @param elementId 节点Id
* @param Id 要查找的节点标示
* @return element
*/
@SuppressWarnings("unchecked")
protected Element findElement( Document document, String fatherElementId, String elementId, String Id ) {
// 节点标示为空
if ( Id == null ) {
return null;
}
// 得到根元素
Element fatherElement = document.getRootElement().getChild(fatherElementId);
// 根元素不存在
if ( fatherElement == null ) {
return null;
}
// 获得子元素列表
List elementList = fatherElement.getChildren(elementId);
// 遍历列表
for ( int i = 0 ; i < elementList.size() ; i++ ) {
// 获得子元素
Element childElement = ( Element )elementList.get(i);
// 比对节点标示
if ( Id.equalsIgnoreCase(childElement.getAttributeValue("id")) ) {
return childElement;
}
}
return null;
}
/**
* 获取指定节点对象的值
* @param document 载入XML文件后获得的Document对象
* @param fatherElementId 父节点Id
* @param elementId 节点Id
* @param Id 要查找的节点标示
* @param paramName 要获取的节点子对象名称
* @return element
*/
protected String getElementValue( Document document, String fatherElementId, String elementId, String Id, String paramName ) {
return getElementValue(findElement(document, fatherElementId, elementId, Id), paramName);
}
/**
* 获取指定节点对象的值
* @param element 节点对象
* @param paramName 要获取的节点子对象名称
* @return element
*/
protected String getElementValue( Element element, String paramName ) {
if ( paramName == null || element.getChild(paramName) == null ) {
return null;
}
return element.getChild(paramName).getText();
}
/**
* 从用户指定的路径载入XML文件
* @param filePath XML文件路径
* @return document
*/
protected Document loadFile( String filePath ) {
Document document = null;
try {
SAXBuilder saxBuilder = new SAXBuilder();
document = saxBuilder.build(new File(filePath));
} catch ( Exception e ) {
e.printStackTrace();
return null;
}
return document;
}
/**
* 保存XML文件到指定的路径
* @param filePath 指定的XML文件存放路径
* @param document XML文件的Document对象
* @param encode XML文件编码,为空代表使用默认的UTF-8编码 可选编码包括GB2312/GB18030或者其他
* @return true-保存成功 false-保存失败
*/
protected boolean saveFile( String filePath, Document document, String encode ) {
Format format = Format.getCompactFormat();
if ( encode != null ) {
format.setEncoding(encode); //设置xml文件的字符集
}
format.setIndent(" "); //设置xml文件的缩进
try {
XMLOutputter xmlOut = new XMLOutputter(format);
FileWriter fileWriter = new FileWriter(filePath);
// 将XML文件写入指定路径
xmlOut.output(document, fileWriter);
} catch ( Exception e ) {
return false;
}
return true;
}
/**
* 过滤字符串,防止XML文件中出现非法字符
* @param sourceString 要过滤的字符串
* @return 过滤后的字符串
*/
protected String formatTextForXML( String sourceString ) {
if ( sourceString == null ) {
return null;
}
int strLen = 0;
StringBuffer reString = new StringBuffer();
String deString = "";
strLen = sourceString.length();
for ( int i = 0 ; i < strLen ; i++ ) {
char ch = sourceString.charAt(i);
switch ( ch ) {
case '<':
deString = "<";
break;
case '>':
deString = ">";
break;
case '\"':
deString = """;
break;
case '&':
deString = "&";
break;
case 13:
deString = "\n";
break;
default:
deString = "" + ch;
}
reString.append(deString);
}
return reString.toString();
}
}2. Demo代码本段Demo代码实现了生成一个符合RSS2.0规范的XML文件接口定义:package org.agricultureonline.common.xml;
import org.jdom.*;
public interface XMLOperator {
public Document initDocument( String title, String linkURL, String description );
public Document loadXMLFile( String filePath );
public Element initElement( String paramName, String paramValue );
public boolean addXMLElement( Document document, Element element );
public boolean editXMLElement( Document document, String Id, String paramName, String paramValue);
public boolean delXMLElement( Document document, String Id);
public boolean saveDocument( String filePath, Document document );
}实现类:package org.agricultureonline.common.xml;
import org.agricultureonline.common.util.BaseXMLOperator;
import org.jdom.Document;
import org.jdom.Element;
public class RSSOperator extends BaseXMLOperator implements XMLOperator {
protected String filePath;
public RSSOperator() {
}
public RSSOperator( String filePath) {
this.filePath = filePath;
}
public String getFilePath() {
return filePath;
}
public void setFilePath(String filePath) {
this.filePath = filePath;
}
public Element initElement( String paramName, String paramValue ) {
return super.createElement(paramName, paramValue);
}
public boolean addXMLElement(Document document, Element element) {
// TODO Auto-generated method stub
return super.addElement(document, "channel", element);
}
public boolean delXMLElement(Document document, String Id) {
// TODO Auto-generated method stub
return super.delElement(document, "channel", "item", Id);
}
public boolean editXMLElement(Document document, String Id, String paramName, String paramValue) {
// TODO Auto-generated method stub
return super.editElement(document, "channel", "item", Id, paramName, paramValue);
}
public Document initDocument( String title, String linkURL, String description ) {
// TODO Auto-generated method stub
Document document = super.createDocument();
Element rssElement = super.createElement("rss", null);
rssElement.setAttribute("version", "2.0");
Element channelEelement = new Element("channel");
Element titleElement = new Element("title");
titleElement.setText(title);
Element linkElement = new Element("link");
linkElement.setText(super.formatTextForXML(linkURL));
Element descriptionElement = new Element("description");
descriptionElement.setText(super.formatTextForXML(description));
channelEelement.addContent(titleElement);
channelEelement.addContent(linkElement);
channelEelement.addContent(descriptionElement);
rssElement.addContent(channelEelement);
document.addContent(rssElement);
return document;
}
public Document loadXMLFile(String filePath) {
// TODO Auto-generated method stub
return super.loadFile(filePath);
}
public boolean saveDocument(String filePath, Document document) {
// TODO Auto-generated method stub
return super.saveFile(filePath, document, "GB18030");
}
}3. 生成的XML文件内容xml version="1.0" encoding="GB18030"?>
<rss version="2.0">
<channel>
<title>测试XMLtitle>
<link>Linklink>
<description>Descriptiondescription>
<item id="111">
<title>网站RSS订阅title>
<link>[url]http://www.agricultureonline.org/[/url]link>
<description>农业在线提供了一个中文植物Wiki平台description>
<pubDate>Wed, 14 Jan 2004 17:16:44 GMTpubDate>
item>
<item id="222">
<title>测试标题title>
<link>http://link>
<description>测试描述description>
<pubDate>Fri Dec 05 18:32:39 CST 2008pubDate>
item>
<item id="333">
<title>测试标题title>
<link>http://link>
<description>测试描述description>
<pubDate>5 Dec 2008 10:33:06 GMTpubDate>
item>
<item id="444">
<title>测试标题title>
<link>http://link>
<description>测试描述description>
<pubDate>5 Dec 2008 10:46:35 GMTpubDate>
item>
channel>
rss>