一套JDOM操作XML文件的Base Class
一、什么是JDOM?
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可以实现什么?
在我写的这个Base Class中,可以实现创建Document对象,初始化Element对象,对Element对象进行有条件的修改、查找操作,对Document对象进行添加、删除节点操作,读取、保存XML文件的操作。这个Base Class是完全通过JDOM来实现操作XML文件,并对XML文件中的特殊字符进行了过滤,防止出现无效的XML文件。
三、Base Class代码
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]http://www./copyleft/gpl.html[/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 <a href="mailto:wmkm0113@Hotmail.com">wmkm0113@Hotmail.com</a> * @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>测试XML</title> <link>Link</link> <description>Description</description> <item id="111"> <title>网站RSS订阅</title> <link>[url]http://www./[/url]</link> <description>农业在线提供了一个中文植物Wiki平台</description> <pubDate>Wed, 14 Jan 2004 17:16:44 GMT</pubDate> </item> <item id="222"> <title>测试标题</title> <link>http://</link> <description>测试描述</description> <pubDate>Fri Dec 05 18:32:39 CST 2008</pubDate> </item> <item id="333"> <title>测试标题</title> <link>http://</link> <description>测试描述</description> <pubDate>5 Dec 2008 10:33:06 GMT</pubDate> </item> <item id="444"> <title>测试标题</title> <link>http://</link> <description>测试描述</description> <pubDate>5 Dec 2008 10:46:35 GMT</pubDate> </item> </channel> </rss> |
|