首 页 网络编程
网页制作 图形图象 操作系统 冲浪宝典
软件教学 认证考试

网络安全 网络办公 行业资讯 评测对比
您当前位置:站长天空 -> 网络编程-> XML教程
Java编程中更新XML文档的常用方法-JSP教程,Java与XML
作者:网友供稿 点击:415
推荐
西部数码-全国虚拟主机10强!20余项虚拟主机管理功能,全国领先!第6代双线路虚拟主机,南北访问畅通无阻!可在线rar解压,自动数据恢复设置虚拟目录等.免费赠送访问统计,企业邮局.Cn域名注册10元/年,自助建站480元起,免费试用7天,满意再付款!P4主机租用799元/月.月付免压金
站内搜索
文章页数:[1] 
本文简要的讨论了java语言编程中更新xml文档的四种常用方法,并且分析这四种方法的优劣。其次,本文还对如何控制java程序输出的xml文档的格式做了展开论述。



jaxp是java api for xml processing的英文字头缩写,中文含义是:用于xml文档处理的使用java语言编写的编程接口。jaxp支持dom、sax、xslt等标准。为了增强jaxp使用上的灵活性,开发者特别为jaxp设计了一个pluggability layer,在pluggability layer的支持之下,jaxp既可以和具体实现dom api、sax api 的各种xml解析器(xml parser,例如apache xerces)联合工作,又可以和具体执行xslt标准的xslt处理器(xslt processor,例如apache xalan)联合工作。应用pluggability layer的好处在于:我们只需要熟悉jaxp各个编程接口的定义即可,而不需要对所采用的具体的xml解析器、xslt处理器有很深入的了解。比如在某个java程序中,通过jaxp调用xml解析器apache crimson对xml文档进行处理,如果我们希望使用别的xml解析器(比如apache xerces),以便提高该程序的性能,那么原程序代码可能不需要任何改变,直接就可以使用(你所需要做的事情只是将包含apache xerces代码的jar文件加入到环境变量classpath中,而将包含apache crimson代码的jar文件在环境变量classpath中删除)。



目前jaxp已经应用的十分普遍了,可以说是java语言中处理xml文档的标准api。有些初学者在学习使用jaxp的过程中,经常会提出这样的问题:我编写的程序对dom tree做了更新,但是当程序退出以后,原始的xml文档并没有改变,还是老样子,如何实现对原始xml文档和dom tree的同步更新呢?咋一看来,在jaxp中似乎没有提供相应的接口/方法/类,这是很多初学者都感到困惑的问题。本文的主旨就在于解决这个问题,简单的介绍几种常用的同步更新原始xml文档和dom tree的方法。为了缩小讨论的范围,本文所涉及的xml解析器仅包括apache crimson和apache xerces,而xslt处理器仅仅使用apache xalan。



方法一:直接读写xml文档



这也许是最笨最原始的办法了。当程序获取dom tree之后,应用dom模型的node接口的各个方法对dom tree进行更新,下一步应该对原始的xml文档进行更新了。我们可以运用递归的办法或者是应用treewalker类,遍历整个dom tree,与此同时,将dom tree的每一个节点/元素依次写入到预先打开的原始xml文档中,当dom tree被遍历完全之后,dom tree和原始的xml文档就实现了同步更新。实际中,这个方法极少使用,不过如果你要编程实现自己的xml解析器,这种方法还是有可能用得上的。



方法二:使用xmldocument类



使用xmldocument类?jaxp中分明没有这个类呀!是不是作者搞错了?没有错!就是使用xmldocument类,确切的说,是使用xmldocument类的write()方法。



在上文已经提到过,jaxp可以和各种各样的xml解析器联合使用,这次我们选用的xml解析器是apache crimson。xmldocument(org.apache.crimson.tree.xmldocument)是apache crimson的一个类,并不包含于标准的jaxp中,难怪在jaxp的文档中找不到xmldocument类的芳踪呢。现在问题出来了,如何应用xmldocument类来实现更新xml文档的功能?在xmldocument类中提供了下面三个write()方法(根据crimson最新的版本------apache crimson 1.1.3):







public void write (outputstream out) throws ioexception

public void write (writer out) throws ioexception

public void write (writer out, string encoding) throws ioexception







上述三个write()方法的主要作用就是输出dom tree中的内容到特定的输出介质中,比如文件输出流、应用程序控制台等等。那么又如何使用上述三个write()方法呢?请看下面的java程序代码片断:





string name="fancy";

documentbuilder parser;

documentbuilderfactory factory = documentbuilderfactory.newinstance();

try

{

parser = factory.newdocumentbuilder();

document doc = parser.parse("user.xml");

element newlink=doc.createelement(name);

doc.getdocumentelement().appendchild(newlink);

((xmldocument)doc).write(new fileoutputstream(new file("xuser1.xml")));

}

catch (exception e)

{

//to log it

}







在上面的代码中,首先创建了一个document对象doc,获取完整的dom tree,然后应用node接口的appendchild()方法,在dom tree的最后追加了一个新节点(fancy),最后调用xmldocument类的write(outputstream out)方法,把dom tree中的内容输出到xuser.xml中(其实也可以输出到user.xml,更新原始的xml文档,在这里为了便于做对比,故而输出到xuser.xml文件中)。需要注意的是不能直接对document对象doc直接调用write()方法,因为jaxp的document接口并没有定义任何write()方法,所以必须将doc由document对象强制转换为xmldocument对象,然后才能调用write()方法,在上面的代码中使用的是write(outputstream out)方法,这个方法使用缺省的utf-8编码输出dom tree中的内容到特定的输出介质中,如果dom tree中包含中文字符,那么输出的结果有可能是乱码,亦即存在所谓的"汉字问题\\",解决的办法是使用write (writer out, string encoding)方法,显式指定输出时的编码,例如将第二个参数设为"gb2312",这时即不存在"汉字问题\\",输出结果能够正常显示中文字符。



完整的例子请参考下列文件: addrecord.java(见附件)、user.xml(见附件)。该例子的运行环境为:windows xp professional、jdk 1.3.1。为了能够正常编译运行addrecord.java这个程序,你需要到网址http://xml.apache.org/dist/crimson/去下载apache crimson,并将所获取的crimson.jar文件加入到环境变量classpath中。



注意:



apache crimson的前身是sun project x parser,后来不知何故,由x parser演变为apache crimson,至今apache crimson的很多代码都是从x parser中直接移植过来的。比如上文用到的xmldocument类,它在x parser中是com.sun.xml.xmldocument,到了apache crimson中摇身一变,就变成了org.apache.crimson.tree.xmldocument类,其实它们的绝大部分代码是一样的,可能就package语句和import语句以及文件开头的一段lience有所不同而已。早期的jaxp是和x parser捆绑在一起的,因此一些老的程序使用了com.sun.xml包,如果你现在重新编译它们,有可能不能通过,肯定就是因为这个原因。后来的jaxp和apache crimson捆绑在一起,比如jaxp 1.1,如果你使用jaxp 1.1,那么不需要额外下载apache crimson,也能够正常编译运行上面的例子(addrecord.java)。最新的jaxp 1.2 ea(early access)改弦更张,采用性能更好的apache xalan和apache xerces分别作为xslt处理器和xml解析器,不能直接支持apache crimson了,所以如果你的开发环境采用了jaxp 1.2 ea或者是java xml pack(内含jaxp 1.2 ea),那么将无法直接编译运行上面的例子(addrecord.java),你需要额外下载并安装apache crimson。



方法三:使用transformerfactory和transformer类



在jaxp中所提供的标准的更新原始xml文档的方法就是调用xslt引擎,亦即使用transformerfactory和transformer类。请看下面的java代码片断:





//首先创建一个domsource对象,该构造函数的参数可以是一个document对象

//doc代表更改后的dom tree。

domsource doms = new domsource (doc);



//创建一个file对象,代表dom tree所包含的数据的输出介质,这是一个xml文件。

file f = new file ("xmloutput.xml");



//创建一个streamresult对象,该构造函数的参数可以取为file对象。

streamresult sr = new streamresult (f);



//下面调用jaxp中的xslt引擎来实现输出dom tree中的数据到xml文件中的功能。

//xslt引擎的输入为domsource对象,输出为streamresut对象。

try

{

//首先创建一个transformerfactory对象,再由此创建transformer对象。transformer

//类相当于一个xslt引擎。通常我们使用它来处理xsl文件,但是在这里我们使

//用它来输出xml文档。

transformerfactory tf=transformerfactory.newinstance();

transformer t=tf.newtransformer ();



//关键的一步, 调用transformer对象 (xslt引擎)的transform()方法,该方法的第一

//个参数是domsource对象,第二个参数是streamresult对象。

t.transform(doms,sr);

}

catch (transformerconfigurationexception tce)

{

system.out.println("transformer configuration exception\n-----");

tce.printstacktrace();

}

catch (transformerexception te)

{

system.out.println ("transformer exception\n---------");

te.printstacktrace ();

}





在实际的应用中,我们可以应用传统的dom api从xml文档中获取dom tree,然后根据实际的需求对dom tree执行各种操作,得到最终的document对象,接下来可以由此document对象创建domsource对象,剩下的事情就是照搬上面的代码了,程序运行完毕后, xmloutput.xml就是你所需要的结果(当然了,你可以随意更改streamresult类构造函数的参数,指定不同的输出介质,而不必是千篇一律的xml文档)。



这个方法最大的好处在于可以随心所欲的控制dom tree中的内容输出到输出介质中的格式,但是光靠transformerfactory类和transformer类并不能实现这个功能,还需要依赖outputkeys类的帮助。 完整的例子请参考下列文件: addrecord2.java(见附件)、user.xml(见附件)。该例子的运行环境为:windows xp professional、jdk 1.3.1。为了能够正常编译运行addrecord2.java这个程序,你需要到网址http://java.sun.com去下载安装jaxp 1.1或者java xml pack(java xml pack已经内含jaxp了)。



outputkeys类



javax.xml.transform.outputkeys类和java.util.properties类配合使用,可以控制jaxp的xslt引擎(transformer类)输出xml文档的格式。请看下面的代码片断:





//首先创建一个transformerfactory对象,再由此创建transformer对象。

transformerfactory tf=transformerfactory.newinstance();

transformer t=tf.newtransformer ();



//获取transformser对象的输出属性,亦即xslt引擎的缺省输出属性,这是一个

//java.util.properties对象。

properties properties = t.getoutputproperties();



//设置新的输出属性:输出字符编码为gb2312,这样可以支持中文字符,xslt引擎所输出

//的xml文档如果包含了中文字符,可以正常显示,不会出现所谓的"汉字问题\\"。

//请留意outputkeys类的字符串常数outputkeys.encoding。

properties.setproperty(outputkeys.encoding,"gb2312");



/更新xslt引擎的输出属性。

t.setoutputproperties(properties);



//调用xslt引擎,按照输出属性中的设置,输出dom tree中的内容到输出介质中。

t.transform(domsource_object,streamresult_object);









从上面的程序代码,我们不难看出,通过设置xslt引擎(transformer类)的输出属性,可以控制dom tree中的内容的输出格式,这对于我们定制输出内容是很有帮助的。那么jaxp的xslt引擎(transformer类)有那些输出属性可以设置呢? javax.xml.transform.outputkeys类定义了很多字符串常数,它们都是可以自由设置的输出属性,常用的输出属性如下所示:



public static final java.lang.string method





可以设为"xml"、"html"、"text"等值。



public static final java.lang.string version





所遵循规范的版本号,如果method设为"xml",那么它的值应该设为"1.0",如果method设为"html",那么它的值应该设为"4.0",如果method设为"text",那么这个输出属性会被忽略。



public static final java.lang.string encoding





设置输出时所采用的编码方式,比如\\"gb2312"、"utf-8"等等,如果将其设置为"gb2312",可以解决所谓的"汉字问题\\"。



public static final java.lang.string omit_xml_declaration



设置输出到xml文档中时是否忽略xml声明,亦即类似于:



<?xml version="1.0" standalone="yes" encoding="utf-8" ?>





这样的代码。它可选的值有"yes"、"no"。



public static final java.lang.string indent





ident设定xslt引擎在输出xml文档时,是否自动添加额外的空格,它可选的值为"yes"、"no"。



public static final java.lang.string media_type



media_type设定输出文档的mime类型。



如果设定xslt引擎的输出属性呢?下面我们来总结一下:



首先是获取xslt引擎(transformer类)的缺省输出属性的集合,这需要使用transformer类的getoutputproperties()方法,返回值是一个java.util.properties对象。



properties properties = transformer.getoutputproperties();





然后是设定新的输出属性,比如:



properties.setproperty(outputkeys.encoding,"gb2312");

properties.setproperty(outputkeys.method,"html");

properties.setproperty(outputkeys.version,"4.0");

………………………………………………………





最后是更新xslt引擎(transformer类)的缺省输出属性的集合,这需要使用transformer类的setoutputproperties()方法,参数是一个java.util.properties对象。



我们编写了一个新的程序,其中应用了outputkeys类,用以控制xslt引擎的输出属性,该程序的架构和前一个程序(addrecord3.java)大致相同,不过输出结果略有不同。完整的代码请参考下列文件: addrecord3.java(见附件)、user.xml(见附件)。该例子的运行环境为:windows xp professional、jdk 1.3.1。为了能够正常编译运行addrecord3.java这个程序,你需要到网址http://java.sun.com去下载安装jaxp 1.1或者java xml pack(java xml pack内含jaxp了)。



方法四:使用xalan xml serializer



方法四其实是方法三的一个变种,它需要apache xalan和apache xerces的支持才能够运行。例子代码如下所示:





//首先创建一个domsource对象,该构造函数的参数可以是一个document对象

//doc代表更改后的dom tree。

domsource domsource = new domsource (doc);



//创建一个domresult对象,临时保存xslt引擎的输出结果。

domresult domresult = new domresult();



//下面调用jaxp中的xslt引擎来实现输出dom tree中的数据到xml文件中的功能。

//xslt引擎的输入为domsource对象,输出为domresut对象。

try

{

//首先创建一个transformerfactory对象,再由此创建transformer对象。transformer

//类相当于一个xslt引擎。通常我们使用它来处理xsl文件,但是在这里我们使

//用它来输出xml文档。

transformerfactory tf=transformerfactory.newinstance();

transformer t=tf.newtransformer ();



//设置xslt引擎的属性(必不可少,否则会产生\\"汉字问题\\")。

properties properties = t.getoutputproperties();

properties.setproperty(outputkeys.encoding,"gb2312");

t.setoutputproperties(properties);



//关键的一步, 调用transformer对象 (xslt引擎)的transform()方法,该方法的第一

//个参数是domsource对象,第二个参数是domresult对象。

t.transform(domsource,domresult);



//创建缺省的xalan xml serializer,使用它将临时存放在domresult对象

//(domresult)中的内容以输出流的形式输出到输出介质中。

serializer serializer = serializerfactory.getserializer

(outputproperties.getdefaultmethodproperties("xml"));



//设置xalan xml serializer的输出属性,这一步必不可少,否则也可能产生

//所谓的"汉字问题\\"。

properties prop=serializer.getoutputformat();

prop.setproperty("encoding","gb2312");

serializer.setoutputformat(prop);



//创建一个file对象,代表dom tree所包含的数据的输出介质,这是一个xml文件。

file f = new file ("xuser3.xml");



//创建文件输出流对象fos,请留意构造函数的参数。

fileoutputstream fos=new fileoutputstream(f);



//设置xalan xml serializer的输出流。

serializer.setoutputstream(fos);



//串行化输出结果。

serializer.asdomserializer().serialize(domresult.getnode());

}

catch (exception tce)

{

tce.printstacktrace();

}







这个方法不太常用,而且似乎有点画蛇添足,所以我们就不展开讨论了。完整的例子请参考下列文件: addrecord4.java(见附件)、user.xml(见附件)。该例子的运行环境为:windows xp professional、jdk 1.3.1。为了能够正常编译运行addrecord4.java这个程序,你需要到网址http://xml.apache.org/dist/去下载安装apache xalan和apache xerces。



或者是到网址http://java.sun.com/xml/download.html去下载安装java xml pack。因为最新的java xml pack(winter 01 版)包含了apache xalan和apache xerces技术在内。



结论:



本文简略的讨论了java语言编程中更新xml文档的四种方法。第一种方法是直接读写xml文件,这种方法十分繁琐,而且比较容易出错,极少使用,除非你需要开发自己的xml parser,否则不会使用这种方法。第二种方法是使用apache crimson的xmldocument类,这种方法极为简单,使用方便,如果你选用apache crimson作为xml解析器,那么不妨使用这种方法,不过这种方法似乎效率不高(源于效率低下的apache crimson),另外,高版本的jaxp或者是java xml pack、jwsdp不直接支持apache crimson,亦即这种方法不通用。第三种方法是使用jaxp的xslt引擎(transformer类)来输出xml文档,这种方法也许是标准的方法了,使用起来十分灵活,特别是可以自如控制输出格式,我们推荐采用这种方法。第四种方法是第三种方法的变种,采用了xalan xml serializer,引入了串行化操作,对于大量文档的修改/输出有优越性,可惜的是要重复设置xslt引擎的属性和xml serializer的输出属性,比较麻烦,而且依赖于apache xalan和apache xerces技术,通用性略显不足。



除了上面讨论的四种方法以外,实际上应用别的api(比如jdom、castor、xml4j、oracle xml parser v2)也有很多办法可以更新xml文档,限于篇幅,在这里就不一一讨论了。



参考文献以及资料来源:



[1]the java web services tutorial, sun microsystems inc.



[2]http://xml.apache.org,apache xml project(crimson、xerces、xalan)



[3]http://www.jguru.com,xml forum



[4]http://forum.java.sun.com,java technology & xml forum




文章整理:站长天空 网址:http://www.z6688.com/
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

文章页数:[1] 


放大字体显示 缩小字体显示 打印文章 推荐给朋友
热门文章
·使用c#如何读取xml文件-.NET教程,XML应用
·利用XMLHTTP无刷新添加数据之Post篇.-ASP教程,XML相关
·VB下如何编写CRC校验程序-.NET教程,VB.Net语言
·Java编程中更新XML文档的常用方法-JSP教程,Java与XML
·JavaScript中获得地址栏参数QueryString-JSP教程,Java技巧及代码
·ASP.NET 2.0中将 GridView 导出到 Excel 文件中-.NET教程,数据库应用
·在red hat linux 10下安装 eclipse 3-JSP教程,Java技巧及代码
·WinCE 5.0边做边学(3)-.NET教程,评论及其它
·用Fireworks制作Logo心得体会-网页设计,Fireworks
·Cookies,SSL,httpclient的多线程处理,HTTP方法-PHP教程,PHP应用
最新文章
·google adsense 2007巡讲大会郑州站总结_网赚技巧
·起点小说网推出小说内容联盟_网赚技巧
·oblog站长访谈系列②:vv博客林林_站长访谈
·学习dreamweaver8了解掌握css层叠样式表_dreamweaver教程
·搞行业网站必须走出去!_站长心得
·网页设计的艺术处理原则_站长心得
·建站常识:如何使用ftp连接虚拟主机?_站长心得
·google rank_google推广
·如何在搜寻结果名中名列前茅_google推广
·几个知名英文搜索引擎的优劣比较_seo网站优化
相关主题
  • java编写TCP方式的通信程序-JSP教程,Java技巧及代码
  • Java编程规则-JSP教程,Java技巧及代码
  • JAVA编码问题的一些理解-JSP教程,Java技巧及代码
  • java编辑多语言的福音--推荐一个经典的多语言文件编辑的插件ResourceBundle Editor-JSP教程,Java技巧及代码
  • JAVA编码问题的一些理解-JSP教程,Java技巧及代码
  • 西部数码虚拟主机

    友情链接
    CNNIC 西部数码
    万网 自助建站
    虚拟主机 asp空间
    域名注册 域名
    域名申请 主页空间
    论坛空间 网站空间
    国际域名 虚拟空间
    空间租用 DDOS防火墙
    成都主机托管 四川主机托管
    主机租用 服务器租用
    网站目录 自助建站
    虚拟主机 网址大全
    软件下载
    自助链接
    虚拟主机资讯 特价虚拟主机
    版权申明:本站文章均来自网络,如有侵权,请联系我们,我们收到后立即删除,谢谢!
    关于我们:站长天空:专业提供最新的站长资讯、在线教程、虚拟主机权威评测、虚拟主机性能对比、网站制作教程,开发教程,站长工具。包括网页制作教程、冲浪宝典、编程参考、操作系统、软件教学、行业动态等。
    特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有。
    发表评论 打印  刷新     关闭