快捷搜索:

用JDOM简化XML编程

JDOM 是一种应用 XML 的独特 Java 对象包,用于快速开拓 XML 利用法度榜样。它的设计包孕 Java 说话的语法甚至语义。然则它是否比现有的 -- 更标准的 -- XML API 好呢?当我们看过一些示例并阐明这个盛行的开放源代码项目的设计目标后,您自己来判断吧。近来这个开放源代码项目已被正式吸收获为 Java 规范要求。

作为开拓职员,您可能据说过 80-20 规则,在其它领域被称为 Pareto 轨则:一种历程或措施能适应所有可能环境的 80%,别的的 20% 则必要根据详细环境来处置惩罚。软件开拓的一定结果是:对付开拓职员而言,有了给定的技巧后就能异常轻易地完成可能要做的事情的 80%。

当然,软件产品和标准并不老是根据 80-20 规则成长的。特其余,Java XML 的缺陷便是这条规则的一个例外。Java 的编程天下拥有很多的 API -- 一些是自己开拓的,一些是由几个大年夜公司开拓并被拟订为标准的 -- 他们供给了办理特殊 XML 义务的成熟办理规划。作为 XML 普遍性的证实,每个新义务都存在着一种新技巧,但若何将它们结合在一路,又若何探求一种相宜的对象去完成必须重复做的义务中的 80% -- 使用 Java 说话的直不雅映象的基础 XML 树操作?JDOM 恰正是用来办理上述问题的一个 XML API。

标记:Java 和 XML

在许多方面,Java 说话已变成供 XML 选择的一种编程说话。因为 Apache 软件基金会和 IBM alphaWorks 所做的创始性事情,现在已有完备的对象链用于创建,操作,传送文档和对 XML 文档进行语法阐发。

然则,虽然许多 Java 开拓职员天天都在应用 XML,Sun 却在将 XML 整合进 Java 平台方面后进了。由于在 XML 成为从商家对商家集成到 Web 站点内容流水化等方面的关键技巧之前,Java 2 平台就已经异常盛行了。Sun 已经应用 JSR 历程使之成为现存 XML API 的开山祖师,这一点已被广泛吸收。今朝最显明的是加入了 JAXP (用于 XML 语法阐发的 Java API),此中包孕了三个软件包:

org.w3c.dom,W3C 保举的用于 XML 标准筹划文档工具模型的 Java 对象

org.xml.sax,用于对 XML 进行语法阐发的事故驱动的简单 API

javax.xml.parsers,工厂化对象,容许利用法度榜样开拓职员得到并设置设置设备摆设摆设特殊的语法阐发器对象

只管对付 Java 开拓职员而言,有了这些软件包是件好事,但它仅仅代表得到了现有 API 标准的正式许可而已,并没有在供给一流的 Java-XML 互操作性方面取得了伟大年夜飞跃。核心 Java 平台所短缺的是将 XML 文档作为 Java 工具操作的直不雅接口。

进入 JDOM。JDOM 是两位闻名的 Java 开拓职员兼作者,Brett Mclaughlin 和 Jason Hunter 的创作成果,2000 年头?年月在类似于 Apache 协议的许可下,JDOM 作为一个开放源代码项目正式开始研发,JDOM 作为一个开放源代码项目正式开始了。它已生长为包孕来自广泛的 Java 开拓职员的投稿、集中反馈及差错修复的系统,并致力于建立一个完备的基于 Java 平台的办理规划,经由过程 Java 代码来造访、操作并输出 XML 数据。

这是 JDOM 得当的 API、哑元

JDOM 能够调换 org.w3c.dom 软件包来有计划地操作 XML 文档。它并不是一个简单的替代品,实际上 JDOM 和 DOM 能够开心地并存。别的,只管它供给的类的封装从设置设置设备摆设摆设和运行阐发器履行平分担了大年夜量事情,但它不认真根据文本输入来对 XML 进行语法阐发。JDOM 建立在现有的 API 的能力之上,正如项目网页所表述的“一个更好的捕鼠器”。

要理解必要备用 API 的缘故原由,就要斟酌 W3C DOM 设计的局限性:

说话自力。DOM 并不是用人们心目中的 Java 说话设计的。虽然这种措施保留了在不合说话中异常相似的 API,它也使那些习气 Java 说话的法度榜样员认为更麻烦。例如:Java 说话内建了一种 String 类,而 DOM 则规范定义了自己的 Text 类。

严格的层次布局。DOM API 直接沿袭了 XML 规范。在 XML 中,每件器械都是一个结点,是以您能在 DOM 中找到一个险些每件器械都可以扩展的基于 Node 的接口和返回 Node 的一系列措施。就多态性的不雅点来讲,它是优秀的,但鉴于如上解释,它在 Java 说话中的利用是艰苦而且不便的,此中从 Node 向叶类型作显式下拉会导致代码的冗长和难以理解。

接口驱动。公共 DOM API 仅由接口组成(Exception 类是一个例外,但恰好足够了)。w3c 对供给实现并不感兴趣,它只对定义接口(对照故意义)感兴趣。但它也意味着作为 Java 法度榜样员应用 API 在创建 XML 工具时增添了分散程度,由于 w3c 标准大年夜量应用工厂化的类和类似的机动的但不直接的模式。在某些利用中,XML 文档是仅由语法阐发器建立的,而从不会由利用法度榜样级代码建立,这是不相关的。然则,跟着 XML 更广泛的应用,并不是所有问题都继承必要由语法阐发器来驱动。利用法度榜样的开拓职员必要一个更方便的措施有计划地构造 XML 工具。

对付法度榜样员,这些约束意味着宏大年夜(在内存占用和接口大年夜小方面)的和难掌握的 API,进修和应用都很难。相反,JDOM 是作为一种轻量级 API 被拟订的,最主要的是它因此 Java 为中间的。它在遵照 DOM 主要规则的根基上撤除了上述毛病:

JDOM 是 Java 平台专用的。只要有可能,API 都应用 Java 说话的内建 String 支持,是以文本值也适用于 String。它还可使用 Java 2 平台的类集,如 List 和 Iterator,给法度榜样员供给了一个富厚的并且和 Java 说话类似的情况。

没有层次性。在 JDOM 中,XML 元素便是 Element 的实例,XML 属性便是 Attribute 的实例,XML 文档本身便是 Document 的实例。因为在 XML 中所有这些都代表了不合的观点,是以它们老是作为自己的类型被引用,而不是作为一个暧昧的“结点”。

类驱动。由于 JDOM 工具便是像 Document、Element 和 Attribute 这些类的直接实例,是以创建一个新 JDOM 工具就如在 Java 说话中应用 new 操作符一样轻易。它还意味着不必要进行工厂化接口设置设置设备摆设摆设 -- JDOM 的应用是刀切斧砍的。

看,没有 Node:建立和操作 JDOM 文档

JDOM 应用标准的 Java 编码模式。只要有可能,它应用 Java new 操作符而不用繁杂的工厂化模式,使工具操作即便对付初学用户也很方便。例如,让我们看一下若何随便应用 JDOM 建立一个简单的 XML 文档。我们将要建立的布局如清单 1 所示。(从参考资料上可下载关于本文的完备代码)

清单 1. 建立 XML 文档样本

Toyota

Celica

1997

green

1ABC234

留意:我们将建立示例文档,鄙人面的清单 2 到清单 7 中有具体描述。

开始,让我们先创建一个根元素,并将其添加到文档中:

清单 2. 创建一个 Document

Element carElement = new Element("car");

Document myDocument = new Document(carElement);

这一步创建一个新 org.jdom.Element,并将其作为 org.jdom.Document myDocument 的根元素。(假如您应用参考资猜中供给的样本代码,请务必导入 org.jdom.*。)由于一个 XML 文档必须不停有一个独一的根元素,以是 Document 将 Element 放在它的构造器中。

下一步,添加 vin 属性:

清单 3. 添加一个 Attribute

carElement.addAttribute(new Attribute("vin", "123fhg5869705iop90"));

添加元素也是很简单的。这里我们添加 make 元素:

清单 4. 元素和子元素

Element make = new Element("make");

make.addContent("Toyota");

carElement.addContent(make);

因为 Element 的 addContent 措施返回 Element,我们也可以这样写:

清单 5. 用简洁形式添加元素

carElement.addContent(new Element("make").addContent("Toyota"));

这两个语句完成了相同的事情。有些人觉得第一个示例可读性更好,然则假如您一次建立许多元素,您会感觉第二个示例可读性更好。要完成构建文档:

清单 6. 添加另外的元素

carElement.addContent(new Element("model").addContent("Celica"));

carElement.addContent(new Element("year").addContent("1997"));

carElement.addContent(new Element("color").addContent("green"));

carElement.addContent(new Element("license")

.addContent("1ABC234").addAttribute("state", "CA"));

您会留意到对付 license 元素,我们不只添加了元素的内容,还为其添加了一个属性,注解许可已被发出了这个状态。这是由于 Element 的 addContent 措施老是返回 Element 本身,而不是一个无效的声明。

用同样的措施添加注释部分或其它标准 XML 类型:

清单 7. 添加一条注释

carElement.addContent(new Comment("Description of a car"));

操作文档也是用类似要领。例如,要引用 year 元素,我们应用 Element 的 getChild 措施:

清单 8. 造访子元素

Element yearElement = carElement.getChild("year");

该语句实际上将返回第一个元素名为 year 的子 Element。 假如没有 year 元素,则调用返回一个空值。留意,我们不必回溯来自任何类似于 DOM Node 接口的返回值 -- Element 的子元素便是 Element。用类似的要领,我们可把 year 元素从文档中撤除:

清单 9. 撤除子元素

boolean removed = carElement.removeChild("year");

此次调用将只撤除 year 元素;文档的另外部分维持不变。

到今朝为止,我们已经涵盖了文档的天生和操作。要将完成的文档输出至节制台,可应用 JDOM 的 XMLOutputter 类:

清单 10. 将 JDOM 转化为 XML 文本

try {

XMLOutputter outputter = new XMLOutputter("", true);

outputter.output(myDocument, System.out);

} catch (java.io.IOException e) {

e.printStackTrace();

}

XMLOutputter 有几个款式选项。这里我们已指定盼望子元素从父元素缩进两个空格,并且盼望元素间有空行。XMLOutputter 可输出到 Writer 或 OutputStream。为输出到文件,我们可以简单地将输出行简化为:

清单 11. 应用 FileWriter 输出 XML

FileWriter writer = new FileWriter("/some/directory/myFile.xml");

outputter.output(myDocument, writer);

writer.close();

与其它措施优越协作:和现有的 XML 对象进行互操作

JDOM 的一个有趣特性是和其它 API 有互操作性。应用 JDOM,不仅能把文档输出到 Stream 或 Reader,还可将文档作为 SAX Event Stream 或作为 DOM Document。这种机动性容许 JDOM 能在多种情况下应用或被添加到已经在应用另一种措施处置惩罚 XML 的系统中去。正如我们在后面一个示例中所看到的,它还容许 JDOM 应用其它的还不能识别 JDOM 的数据布局的 XML 对象。

JDOM 的另一个用场是它能够读取并操作现有的 XML 数据。应用 org.jdom.input 中的一个类可以涉猎布局很规范的 XML 文件。在这个示例中我们应用 SAXBuilder:

清单 12. 应用 SAXBuilder 对 XML 文件进行语法阐发

try {

SAXBuilder builder = new SAXBuilder();

Document anotherDocument =

builder.build(new File("/some/directory/sample.xml"));

} catch(JDOMException e) {

e.printStackTrace();

} catch(NullPointerException e) {

e.printStackTrace();

}

您可以用清单 2 到清单 7 中显示的措施来操作经由过程这个历程建立的文档。

JDOM 的另一个实用利用法度榜样将其与 Apache 的 Xalan 产品结合在一路(请参阅参考资料)。应用上面的汽车示例,我们将为在线汽车经销商建立一个 Web 页面,显示特定汽车的具体信息。首先,假设我们上面建立的文档显示我们筹备出现给用户的汽车的信息。下一步,我们将把这个 JDOM Document 与一个 XSL 样式表结合起来并把 HTML 款式的结果输出到 servlet 的 OutputStream 上以便在用户的浏览器中显示。

在本例中,我们筹备应用的 XSL 样式表被称为 car.xsl:

清单 13. 用于将汽车记录转换为 HTML 的 XSL 文档

VIN:

Year:

Color:

现在我们将把 org.jdom.Document 转换为 DOM Document,并将其与显示我们的 XSL 和 OutputStream 的文件一路供给给 Xalan,OutputStream 是我们从我们假定的应用 servlet(如清单 14 所示)的利用办事器上获取的。

清单 14. 应用 JDOM 和 Xalan 创建 HTML 文档

TransformerFactory tFactory = TransformerFactory.newInstance();

// Make the input sources for the XML and XSLT documents

org.jdom.output.DOMOutputter outputter = new org.jdom.output.DOMOutputter();

org.w3c.dom.Document domDocument = outputter.output(myDocument);

javax.xml.transform.Source xmlSource =

new javax.xml.transform.dom.DOMSource(domDocument);

StreamSource xsltSource =

new StreamSource(new FileInputStream("/some/directory/car.xsl"));

// Make the output result for the finished document using

// the HTTPResponse OutputStream

StreamResult xmlResult = new StreamResult(response.getOutputStream());

// Get a XSLT transformer

Transformer transformer = tFactory.newTransformer(xsltSource);

// Do the transform

transformer.transform(xmlSource, xmlResult);

在这个示例中,输出是经由过程 Java servlet 的 HTTPResponse OutputStream 流出。然而,输出流可以象早期的应用 XMLOutputter 的实例一样简单的经由过程文件流输出。我们应用 DOMOutputter 为 Xalan 天生 XML 源代码。然则我们可以天生相同的输出,措施是应用 XMLOutputter 将我们的 XML 文档作为 String 输出并使其进入 StreamSource。说到机动性:JDOM 可将它的布局作为 String、SAX Event Stream 或 DOM Document 输出。这容许 JDOM 与能把任何这些模型作为输入的对象一路事情。(关于附加功能,请造访 JDOM Web 站点的 contrib 包,在那里您将发明一个基于 JDOM 对象的宝库,可供给基于 JDBC ResultSet 的构建器、XPATH 实现措施和其它更多对象。)

在短短几行代码中,JDOM 启用了许多功能,我们已经在 XML 中阐发过并有计划地创建了 XML 文档,操作了那些文档,并应用它们孕育发生 XML 驱动的 Web 页面。

Sun 和 JDOM:名字里包孕了些什么?

JDOM 的 1.0 正式发行版可能与其在 Java Community Process 中的一直成长偏向切合。作为 JSR-102 提交的 JDOM 已经赞许成为了核心 Java 平台的终极包孕部分。Sun 对此的评价是:“JDOM 确凿显着地比早期的 API 更易于应用,是以我们信托它将成为 Java 平台有用的附加物。”据 JSR 走漏,JDOM 1.0 发行版的包装可能由 "org.jdom" 变为 "javax.xml"。只管前景乐不雅,但开拓职员可能终极不得不改变他们的代码来应用新代码。

JDOM 的生长:前景一瞥

正如斯文所提的那样,JDOM 项目已经宣布了它的 Beta 6 版本。以致在 beta 状态下,对付许多真实天下中的实现措施来说,JDOM 已经被证实是稳定的一种了。只管大年夜部分的 API 已经牢固了,但在一些领域中仍在进行一些会对现有的接口造成潜在影响的事情。是以,在这点上,任何在进行的开拓项目都不必要由于害怕一个差错多多的实现措施而逃避 JDOM,然则要斟酌这样一个事实:某些措施布局或某些语义仍有可能在终极宣布和被核心 Java API 所采纳之前发生改变。(请参阅名字里包孕了些什么?)

JDOM 紧接着要做的是致力于稳定 API 并对实现措施的各方面机能问题作出评估。其它方面有所进展,但也造成了对一些利用法度榜样开拓职员的阻碍,包括支持 DTD 实体和其它不太常见的构造。沿着这条路再进一步便是对 XPATH(它是一种象 XSLT 这样的利用法度榜样所特有的 XML 路径说话)的核心支持以及更多地集成 XML 数据源。

那么,概况地说,JDOM 是否比现有的 XML API 好呢?假如您贪图 Java,那谜底可能是“是的”。JDOM 并非意味着将取代您所喜好的语法阐发或 XML 敏感型数据库,但其设计原则有助于为试图掌握 XML 天下的新老 Java 开拓职员供给快速的进修道路。

参考资料

请下载样本代码(一个 Java 类的源代码版本和经编译的版本,包括本文应用的所有示例代码以及 XML 和 XSL 文件)。您会必要在类路径中的 JDOM、Xerces 和 Xalan 来运行代码。

如想得到 JDOM 的最新版本、在线 API 文档及更多信息,请造访 JDOM 网站。

如想得到有关 Xalan、Xerces 和其它 Java XML 产品的更多信息,请造访 Apache XML 网站。

请造访 XML 网站,获取一样平常 XML 信息、教程和资本。

请不要忘怀 developerWorks XML 专区,那儿有大年夜量和 XML 有关的内容。

IBM 的 alphaWorks 网站为 Java 和 XML 开拓职员供给了几个对象:

XML Parser for Java 包孕了对 DOM 级别 1 和 SAX 级别 1 规范的公开的和稳定的支持。

为了诊断对 XML Schema 说话的不精确应用,请考试测验 XML Schema Quality Checker。

XML Security Suite 供给了多种安然性功能,例如数字署名、元素式的加密和造访节制。

使用 XSL Editor 来测试和编辑您的 XSL。

IBM XML parser for Java (XML4J) 是一个节制 XML 文档的便利对象。“应用 IBM XML 阐发器”会教您它的用法。(IBM PartnerWorld for Developers,2000 年 1 月)

JDOM 的创建者都是有名作家。我们保举您涉猎 Jason Hunter 的 “Java Servlet Programming,第 2 版” (O'Reilly,2001 年 4 月)和 Brett McLaughlin 的 "Java and XML" (O'Reilly,2000 年 6 月)。

除此之外, 以下是 Brett 为 developerWorks 撰写的几篇相关文章:

“从 DOM 转换”(2001 年 4 月)

“从 SAX 转换”(2001 年 4 月)

“应用 JDOM 和 XSLT”(2001 年 3 月)

“有关 JAXP 的统统”(2000 年 11 月)

“JAXP 重温” (2000 年 12 月)

William Phillips 和 Gary Cole 所撰写的“节制 DOM”(developerWorks,2001 年 4 月)向 Java 开拓职员先容了 DirectDOM。

请参加面向 Java 开拓职员的 developerWorks XML 对象和 API 评论争论。

这儿有更多有关应用 DOM 来把 XML 文档整合入利用法度榜样的更多信息。

请看 MegObjectExamplePlugin 若何把 Web 页面转换成“低媒体”页面。

关于作者

Wes Biggs 已经为包括 Los Angeles Times、USWeb 和 Elite Information Systems 在内的一些公司开拓了因特网利用。他常常为开放源代码 Java 项目撰稿,并掩护着自由软件基金的 gnu.regexp 的按期宣布包。可经由过程 wes@tralfamadore.com 联系 Wes。

Harry Evans 在软件设计和利用工程方面的履历包括大年夜多半在启动情况中的几个基于 Web 和因特网敏感型的产品的设计。他涉足过产品生命周期的所有阶段,从快速利用开拓到传统产品集成。可经由过程 harry@tralfamadore.com 联系 Harry。

您可能还会对下面的文章感兴趣: