分享

一套JDOM操作XML文件的Base Class

 fenyu8 2011-07-01
一套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>

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多