search 2013 adfgs
作者:Sky.Jian | 可以任意转载, 但转载时务必以超链接形式标明文章原始出处 和 作者信息 及 版权声明
链接:http://isky000.com/software/%e9%80%9a%e8%bf%87jive%e5%85%a5%e9%97%a8jdom%e7%9a%84%e5%ba%94%e7%94%a8 | del.icio.us | Twitter it

玩了这么久的jive论坛了,以前一直沉迷于他在设计上那优雅的模式运用,但是对他处理自己的属性文件(jive_config.xml)却是一直没有怎么在意,可以说唯一的了解就是只知道他都是通过com.jivesoftware.forum包里面的JiveGlobals类来处理自己的配置文件里面的各种属性(其实是错误的),至于怎么处理的就不得而知了。
最近总感觉自己应该好好学习一下XML文件的处理了。有了想法就应该马上动手,所以马上就打开了那可爱的MyIE2,不管三七二十一,先Google一番再说。一下子眼前关于XML文件处理的技术资料看得我眼花缭乱。看来Google能当搜索老大是有道理的。在里面遨游一番后大概了解到现在主要的几种XMl处理解决方案:
一、 DOM
DOM是用与平台和语言无关的方式表示 XML 文档的官方 W3C 标准,以层次结构组织的节点或信息片断的集合。这个层次结构允许开发人员在树中寻找特定信息。DOM 以及广义的基于树的处理具有几个优点。首先,由于树在内存中是持久的,因此可以修改它以便应用程序能对数据和结构作出更改。它还可以在任何时候在树中上下导航,而不是像 SAX 那样是一次性的处理。DOM 使用起来也要简单得多。
二、 SAX
这种处理的优点非常类似于流媒体的优点。分析能够立即开始,而不是等待所有的数据被处理。而且,由于应用程序只是在读取数据时检查数据,因此不需要将数据存储在内存中。这对于大型文档来说是个巨大的优点。事实上,应用程序甚至不必解析整个文档;它可以在某个条件得到满足时停止解析。一般来说,SAX 还比它的替代者 DOM 快许多。
三、 JDOM
JDOM 的目的是成为 Java 特定文档模型,它简化与 XML 的交互并且比使用 DOM 实现更快。由于是第一个 Java 特定模型,JDOM 一直得到大力推广和促进。正在考虑通过“Java 规范请求 JSR-102”将它最终用作“Java 标准扩展”。从 2000 年初就已经开始了 JDOM 开发。JDOM 文档声明其目的是“使用 20%(或更少)的精力解决 80%(或更多)Java/XML 问题”(根据学习曲线假定为 20%)。JDOM 对于大多数 Java/XML 应用程序来说当然是有用的,并且大多数开发者发现 API 比 DOM 容易理解得多。
四、 DOM4J
虽然 DOM4J 代表了完全独立的开发结果,但最初,它是 JDOM 的一种智能分支。它合并了许多超出基本 XML 文档表示的功能,包括集成的 XPath 支持、XML Schema 支持以及用于大文档或流化文档的基于事件的处理。它还提供了构建文档表示的选项,它通过 DOM4J API 和标准 DOM 接口具有并行访问功能。从 2000 下半年开始,它就一直处于开发之中。 为支持所有这些功能,DOM4J 使用接口和抽象基本类方法。DOM4J 大量使用了 API 中的 Collections 类,但是在许多情况下,它还提供一些替代方法以允许更好的性能或更直接的编码方法。直接好处是,虽然 DOM4J 付出了更复杂的 API 的代价,但是它提供了比 JDOM 大得多的灵活性。 在添加灵活性、XPath 集成和对大文档处理的目标时,DOM4J 的目标与 JDOM 是一样的:针对 Java 开发者的易用性和直观操作。它还致力于成为比 JDOM 更完整的解决方案,实现在本质上处理所有 Java/XML 问题的目标。在完成该目标时,它比 JDOM 更少强调防止不正确的应用程序行为。 DOM4J 是一个非常非常优秀的Java XML API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件。如今你可以看到越来越多的 Java 软件都在使用 DOM4J 来读写 XML,特别值得一提的是连 Sun 的 JAXM 也在用 DOM4J。
上面这些都是Google半天后得一些成果,后面就需要我自己来先选一个好好深入探个究竟了。在Google的时候还了解到自己一直爱不释手的JIVE就是用JDOM处理的XML文件,于是决定:不管谁优谁劣,先看看JDOM再说吧!
在JIVE中, JDOM主要是操作配置文件来对系统进行各种配置。比如系统的locale,字符集,数据库连接信息等等。先看看他具体怎么实现的吧:
这些属性全部是写在一个叫jive_config.xml的文件中.这个XML文件的排列方式和使用方式是这样:


 
  CN
  zh
  Asia/Shanghai
  GBK
 


其中
是整个文档的根元素,所有的其他元素都必需在这个根元素里面
系统中处理此文档的一个关键类就是XMLProperties类,其中有以下几个主要的操作方法:
读取:getProperty(name) ;通过name参数来读取需要的属性,其中name其实就是元素名称,要读取的就是元素的值。
新增修改: setProperty(name, value);通过name参数和value参数来设置(修改和新增)属性,同getProperty(name)的name参数一样就是元素(也就是属性名),而value就是要设置的属性值。
删除: deleteProperty(name) ;通过给定的属性名name参数来删除此属性(包括名和值,其实就是在xml文件中删除此元素结点)
系统还有一个与XMLProperties相对应JiveGlobals类,在里面有与之对应的三个方法:getJiveProperty();setJiveProperty();deleteJiveProperty()。我们还是选一个方法看看其具体实现吧:
public static String getJiveProperty(String name) {
if (properties == null) {
loadProperties();//这里是先load出XML文件必要属性
}
return properties.getProperty(name);
}

我想大家一眼就能看明白这个方法的实现,在return 后的properties就是XMLProperties类的一个对象(这个可以在JiveGlobals的loadProperties方法中看出),这里就直接通过该对象调用XMLProperties的getProperty方法。相当于这里只是把XMLProperties类的方法通过JiveGlobals类来给“外界”使用,而不是直接通过XMLProperties来用。那这几个方法具体怎么用呢?其实非常简单。
先看看我怎么取language属性的值吧:JiveGlobals.getJiveProperty(“email.fromEmail”),简单吧,其实这都归功于XMLProperties中对JDOM的使用。
我们先看看XMLProperties:吧
public class XMLProperties {

private File file;
private Document doc;
private Map propertyCache = new HashMap();

public XMLProperties(String fileName) throws IOException {
this.file = new File(fileName);

…… //这里省略部分构造函数

try {
SAXBuilder builder = new SAXBuilder();
DataUnformatFilter format = new DataUnformatFilter();
builder.setXMLFilter(format);
doc = builder.build(file);
}
catch (Exception e) {
System.err.println("Error creating XML properties file: ");
e.printStackTrace();
throw new IOException(e.getMessage());
}
}

public synchronized String getProperty(String name) {
String value = (String)propertyCache.get(name);
if (value != null) {
return value;
}
String[] propName = parsePropertyName(name);
Element element = doc.getRootElement();
//根据解析名称字符串得到的名称结点数组寻找该属性值所在的结点.
for (int i = 0; i < propName.length; i++) { element = element.getChild(propName[i]); if (element == null) { return null; } } //通过JDOM中Element类非常简单就取得了需要的value值也就是属性值. value = element.getText(); if ("".equals(value)) { return null; } else { //这里是将属性放到缓存里面,方便以后更快读取. value = value.trim(); propertyCache.put(name, value); return value; } } /** * 通过父元素查找他的所有子元素 * @param 父结点(元素)的名称. * @return 所有子元素的名称组成的字符串数组. */ public String [] getChildrenProperties(String parent) { String[] propName = parsePropertyName(parent); Element element = doc.getRootElement(); for (int i = 0; i < propName.length; i++) { element = element.getChild(propName[i]); if (element == null) { return new String [] { }; } } List children = element.getChildren(); int childCount = children.size(); String [] childrenNames = new String[childCount]; for (int i=0; i我们看看XMLProperties类中的实现吧,从头开始吧:
一开始就在构造函数里面开始就建立了一个JDOM的Document(xml文档类型)空对象doc,然后通过SAXBuilder build出来,不过还借助了DataUnformatFilter的帮助,后面将多次用到他。接着看看取得xml文档中的的属性吧(getProperty(String name)方法)。 关键代码从由属性名称取得结点数组后面开始,首先是通过doc取得文档根结点,然后就是通过JDOM的Element的getChild()来一层一层往里找需要读取的属性所在的结点, 然后就是很轻松的通过getText()来读取这个结点元素的value值了。这里还只是读取XML文件中特定结点元素的value值的操作,不过其他还有修改添加删除方面的操作其实也非常简单,下面的setProperty(String name,String value)和deleteProperty(String name)方法就是修改添加删除操作,很多地方和前面的getProperty(String name)差不多,setProperty里面也是先找名称为name的结点,找到就就用setText()来修改其value,找不到就先通过Element的addContent(String name)添加一个结点元素,然后再给他setText()。而deleteProperty(String name)也同样是先通过的Element找到需要删除的属性所在的结点元素的上一级结点,然后就是他的removeChild(String name)出场移除结点的了。这里有个地方需要注意的,就是对文档的改动其实都是再内存里面的改动,最后是需要将改动保存到磁盘上面的xml文件上面的,所以JIVE的setProperty(String name,String value)和deleteProperty (String name)方法最后都调用了一个saveProperties()方法,这就是保存文档数据的一个方法,大家应该看到了,这里JIVE用到了JDOM的XMLOutputter 的output(Document,OutputStream)去做写和格式化的工作.为了在遇到错误的时候不至于把数据丢失或损坏,先把数据写到临时文件上面去,如果没有什么错误,再删除原来的文件并把临时文件改成属性文件
到这里大家应该对JDOM有了一个大概的了解了吧?最后再总结一下吧,在JIVE的XMLProperties中,首先通过JDOM的SAXBuilder类型的builder来build出一个JDOM的Document类型的doc,后面就是对这个doc进行操作了,通过doc获取其根结点(元素),找到我们需要的element,然后再通过Element的setText(String)和getText()方法来对其value进行set、get,或者通过addContent(String)和removeChild()来add或remove其child ,仅此而已。
看到这里是不是觉得JDOM真的很简单呢?其实事实本就是如此,JDOM的特点就是简单易用。不过千万不要以为JDOM旧只有这么一点点功能,其实这还只是他很小的一点点功能,但是这些却是我们用到的比较频繁的一些功能,要知道JDOM文档中申明其目的就是“使用 20%(或更少)的精力解决 80%(或更多)Java/XML 问题”!至于其他的一些功能就留给读者自己钻研学习去吧,我在此只做个抛砖引玉,就不在此罗嗦了!

看完了要说点啥么?