Java读写XML?DOM4J一出,谁与争锋
一个开源XML解析包DOM4J是被出品的, 它在其网站之中有着如此这般的定义。
首先, Dom4j好用, 在Java里对XML、XPath和XSLT开放, 借助Java语言, 且配有全然针对DOM、SAX和JAXP的内容。然后用Java的它, 这Dom4j容易使用, 在Java里借助Java语言开放关于XML、XPath和XMTL且有针对DOM、SAX和JAXP的完整内容。
Dom4j是个易用的开源库, 用于XML, XPath以及XSLT , 它运用在Java平台, 采用了Java集合框架, 且完全支持DOM, SAX还有JAXP。
DOM4J运用之际极为简易, 只要晓得基础的XML - DOM模式, 便能够运用, 然而其自身所带的指南仅仅只有简短的一页(html格式), 不过阐述得颇为完善, 国内的中文资料数量稀少, 所以我撰写这个篇幅短小的教程以便利大家运用, 这篇文章仅仅讲述基础的用法, 要是需要深入地运用, 请自行摸索或者查找别的资料。
之前, 看过IBM社区的文章啦(此文可参见附录), 文章里提到了一些XML解析包的性能比较情况,其中, DOM4J的性能, 是非常出色的, 在多项测试里面, 它的名次名列前茅。(实际上, DOM4J的官方文档当中也引用了这个比较结果呢)所以, 这次的项目当中, 我采用了DOM4J作为XML解析工具。
在国内较为流行的情形是运用JDOM用作解析器, 二者各自具备擅长之处, 然而DOM4J最为显著的特色在于运用数量众多的接口, 这同样是它被视作比JDOM更为灵活的关键缘由。有大师讲过这样的话, “面向接口编程”。采用DOM4J的人数已经越来越多。要是你擅长运用JDOM, 不妨持续沿用下去, 仅当作了解与比较看看本篇文章, 要是你正打算采用一种解析器, 倒不如选用DOM4J。
它的主要接口都在org.dom4j这个包里定义:
定义了XML的属性
按照能够包含子节点的节点, 像那种XML , 其中的元素, 和文档, 去定义了一个公共的行为。
CDATA CDATA 定义了XML CDATA 区域
它属于一种标识接口, 该接口用以标识那基于字符的节点 , 比如说, 像CDATA , 还有Text。
定义了XML注释的行为
定义了XML文档
定义XML 声明
定义XML 元素
定义了 对象的处理器
被 使用,用于取得当前正在处理的路径层次信息
定义 XML
在dom4j里, 负责为所有XML节点将多态行为予以构建的是Node, 此即为Node的作用, 没错, 就是Node。
定义了在dom4j节点中产生的一个滤镜或谓词的行为()
n n 定义 XML 处理指令.
用于实现模式.
要剖析一个字符串, XPath会给出一个XPath表达式, XPath就是这样的。
看名字大致就知道它们的涵义如何了。
要想弄懂这套接口,关键的是要明白接口的继承关系:
java.lang.
org.dom4j.Node
org.dom4j.
org.dom4j.
org.dom4j.
org.dom4j.
org.dom4j.
org.dom4j.CDATA
org.dom4j.
org.dom4j.Text
org.dom4j.
org.dom4j.
org.dom4j.n
一眼就能看得清清楚楚, 好多事情都进而明晰了, 其中大多是从Node继承而来的, 了解这些关联, 往后编写程序便不会出现状况了。
简介播报
下面给出了一些例子, 这些例子的一部分是从DOM4J自带的文档当中摘取出来的, 简单讲述一下怎样应用。
读写XML文档, 主要是依赖于org.dom4j.io包, 这个包之中, 会提供和两类不一样的方式, 不过, 调用的方式却是相同的。这便是依靠接口所形成的好处。
// 从文件读取XML,输入文件名,返回XML文档
read( ) n, {
= new ();
= .read(new File());
当中, 那个read方法是经过重载的, 能够从File、Url等诸多不一样的源予以读取, 所获取到的对象便代表了整个XML。
按照本人自身的经验, 所读取的字符编码会依据 XML 文件头所定义的编码去进行转换。要是碰到乱码问题, 需留意要让各处的编码名称维持一致才行呢。
读完之后的第二步情形是收获获取Root节点, 知晓熟悉XML的人都清楚明白, 所有的一切XML分析都是从Root元素起始开头的。
( doc){
doc.();
DOM4J提供至少3种遍历节点的方法:
// 枚举所有子节点
for ( i = root.(); i.(); ) {
= () i.next();
// 枚举名称为foo的节点
对于, i被赋值为根节点的foo属性值, 当i能够执行其对应的方法时, 持续循环。
foo = () i.next();
for ( i = root.(); i.(); ) {
= () i.next();
递归也可以采用作为枚举手段,但文档中提供了另外的做法
void () {
(());
void ( ) {
声明整型变量i初始化为0, 同时声明另一个变量size, 其值为某个未知的值, 在i小于size的情况下, 执行i自增操作, 如此循环。
Node node = .node(i);
if (node ) {
(() node);
} else { // do ....
有着极大兴奋之感所在的是, DOM4J相对应方面的支持, 透过这样显著地能够大幅裁减代码数量, 而且清晰明白易于理解。知晓设计模式内容的那些人都清楚, 它属于GOF设计模式里被标识其一此类情况状态下。它主要所具备的原理就是, 两种类别彼此之间相互持有对方引用状态情况, 并且其中一种以之作为去开展访问诸多方面情况。我们来查看在DOM4J之中的模式情形(快速文档当中没有予以提供这种相关内容呈现)。
只需要自定一个类实现接口即可。
class {
void visit( ){
.out.(.());
void visit( attr){
.out.(attr.());
调用: root.(new ())
接口给出了多种Visit()的重载形式, 针对XML里不同的对象, 会采用不一样的方式去进行访问。上面所给出的是简单的实现, 通常较为常用的就是这两个。其中是DOM4J授予的默认适配器, 接口具备一种模式, 这种模式给出了各类visit(*)的空实现, 目的在于简化代码。
留心, 这是会自动对所有子节点进行遍历的。要是属于root.()的情况, 就会去遍历子节点。我头一回使用之际, 觉得是得靠自己去遍历, 于是在递归里进行调用, 其结果可想而知。
DOM4J具备对XPath的良好支持, 比如说, 若要访问一个节点, 能够直接借助XPath来进行选择。
void bar( ) {
List list = .( //foo/bar );
Node node = .(//foo/bar/);
name = node.( @name );
比如说, 要是你打算去查找XHTML文档里全部的超链接, 下面这样子的代码能够达成目标:
void ( ) {
List list = .( //a/@href );
对于, 迭代器等于列表的那种情况, 迭代器存在的那种情况, (这里是一个代码块的起始)
= () iter.next();
url = .();
字符串与XML的转换
有时候经常要用到字符串转换为XML或反之,
= ...;
text = .asXML();
= .(text);
(
// load the using JAXP
= .();
= .(
new ( )
// now lets style the given
= new ( );
= new ();
.( , );
// the
= .();
一般创建XML是写文件前的工作,这就像一样容易。
() {
= .();
root = .("root");
.(name, James)
.(, UK)
.(James );
.(name, Bob)
.(, US)
.(Bob );
有一种简单的输出方式, 是把一个或者任意的Node, 借助write方法来进行输出。
out = new ( foo.xml );
如果你想改变输出的格式,比如美化输出或缩减格式,可以用类
void write( ) {
= new (
new ( .xml )
.write( );
= .();
= new ( .out, );
.write( );
= .();
= new ( .out, );
.write( );
有没有这样的情况, DOM4J是不是相当简单, 当然, 一些比较复杂的应用并没有被提及, 也就是那种类似举例的情况等等。要是你因此心动了, 那就一道儿来使用DOM4J。
应用播报
本文着重探讨了运用dom4j解析XML的基础性问题, 其中涵盖了构建XML文档, 进行添加节点、修改节点、删除节点的操作, 还涉及到格式化输出以及中文方面的问题, 它能够作为dom4j的入门资料。
dom4j是一个开源项目, 运用此项目者, 多将其运用重点放在XML的解析环节。该项目自2001年7月对外发布第一版开始, 便持续不断地推出多个不同的版本, 直至当下最新的版本号为1.6。
dom4j是专门面向Java进行开发的, 其使用起来极为简便、直观, 在Java领域当中, dom4j正在疾速普及。
那.5的完整版大概有13M, 它是一个叫dom4j - 1.5.zip的压缩包, 解压以后会有一个dom4j - 1.5.jar文件, 这个就是应用的时候需要引入的类包, 除此之外还有一个jaxen - 1.1 - beta - 4.jar文件, 通常也是需要引入的, 不然执行的时候可能会抛出java.lang.: org/jaxen/异常, 其他的包可以选择去使用它。
示例XML文档(holen.xml)
有个目的是为了方便进行述说工作, 首先得去看一个XML文档, 而往后的操作全部都是以这个文档作为基础情况的。
这是一份XML文档, 其场景设定为网络书店, 其中存在诸多书籍, 每一本都具备两个属性, 其一为书籍名称, 其二是是否展示, 最终还有一项内容是这些书籍的拥有者相关信息。
* 建立一个XML文档,文档名由输入属性决定
* @param 需建立的文件名
* @ 返回操作结果, 0表失败, 1表成功
int ( ){
/** 返回操作结果, 0表失败, 1表成功 */
/** 建立对象*/
= .();
/** 建立XML文档的根books */
= .("books");
/** 加入一行注释 */
.(“这是针对dom4j的一次测试, 霍伦, 2004年9月11日”)
/** 加入第一个book节点 */
= .("book");
/** 加入show属性内容 */
.("show","yes");
/** 加入title节点 */
= .("title");
/** 为title设置内容 */
.("Dom4j ");
/** 类似的完成后两个book */
= .("book");
.("show","yes");
= .("title");
.(" ");
= .("book");
.("show","no");
= .("title");
.(" in ");
/** 加入owner节点 */
= .("owner");
.("O'");
/** 将中的内容写入文件中 */
= new (new (new File()));
.write();
/** 执行成功,需返回1 */
= .();
通过这句定义一个XML文档对象。
= .("books");
通过这句定义一个XML元素,这里添加的是根节点。
有几个重要的方法:
l :添加注释
l :添加属性
l :添加子元素
最终借助生成物理文件, 默认状况下生成的 XML 文件排版样式较为杂乱, 能够经由类的括号方法或者括号方法进行格式化输出, 默认运用括号方法, 呈现得比较紧凑, 这一点会在后续详尽叙说。
有三项修改任务,依次为:
倘若book这个节点里show这样的属性所含的内容是yes, 那么就将其修改为no。
l 把owner项内容改为,并添加date节点
l 若title内容为Dom4j ,则删除该节点
* 修改XML文件中内容,并
* 重点掌握dom4j中如何添加节点,修改节点,删除节点
* @param 修改对象文件
* @param 修改后
* @ 返回操作结果, 0表失败, 1表成功
int ( , ){
= new ();
= .read(new File());
**修改内容之一**: 若book节点当中, show属性部分所呈现的内容是yes, 那么就将其修改为no。
/** 先用xpath查找对象 */
iter = list.();
while(iter.()){
= ()iter.next();
if(.().("yes")){
.("no");
* 修改内容之二: 把owner项内容改为
而且, 在owner节点里头加入date节点, date节点所包含的内容为2004 - 09 - 1, 并且, 还针对date节点增添一个属性type。
list = .("/books/owner" );
iter = list.();
= ()iter.next();
.("");
= .("date");
