﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-小猪快跑JAVA技术-随笔分类-新知识学习</title><link>http://www.blogjava.net/fjq639/category/6169.html</link><description>JAVA技术</description><language>zh-cn</language><lastBuildDate>Wed, 28 Feb 2007 03:39:26 GMT</lastBuildDate><pubDate>Wed, 28 Feb 2007 03:39:26 GMT</pubDate><ttl>60</ttl><item><title>Junit概述</title><link>http://www.blogjava.net/fjq639/archive/2005/12/20/24833.html</link><dc:creator>黑石</dc:creator><author>黑石</author><pubDate>Tue, 20 Dec 2005 10:02:00 GMT</pubDate><guid>http://www.blogjava.net/fjq639/archive/2005/12/20/24833.html</guid><wfw:comment>http://www.blogjava.net/fjq639/comments/24833.html</wfw:comment><comments>http://www.blogjava.net/fjq639/archive/2005/12/20/24833.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/fjq639/comments/commentRss/24833.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fjq639/services/trackbacks/24833.html</trackback:ping><description><![CDATA[1、概述<BR>　　Junit测试是程序员测试，即所谓白盒测试，因为程序员知道被测试的软件如何（How）完成功能和完成什么样（What）的功能。<BR>　　Junit本质上是一套框架，即开发者制定了一套条条框框，遵循这此条条框框要求编写测试代码，如继承某个类，实现某个接口，就可以用Junit进行自动测试了。<BR>　　由于Junit相对独立于所编写的代码，可以测试代码的编写可以先于实现代码的编写，XP 中推崇的 test first design的实现有了现成的手段：用Junit写测试代码，写实现代码，运行测试，测试失败，修改实现代码，再运行测试，直到测试成功。以后对代码的修改和优化，运行测试成功，则修改成功。<BR>　　Java 下的 team 开发，采用 cvs(版本控制) + ant(项目管理) + junit(集成测试) 的模式时，通过对ant的配置，可以很简单地实现测试自动化。<BR><BR>　　对不同性质的被测对象，如Class，Jsp，Servlet，Ejb等，Junit有不同的使用技巧，以后慢慢地分别讲叙。以下以Class测试为例讲解，除非特殊说明。<BR><BR>2、下载安装<BR><BR><BR>去Junit主页下载最新版本3.8.1程序包junit-3.8.1.zip<BR><BR>用winzip或unzip将junit-3.8.1.zip解压缩到某一目录名为$JUNITHOME<BR><BR>将junit.jar和$JUNITHOME/junit加入到CLASSPATH中，加入后者只因为测试例程在那个目录下。<BR><BR>注意不要将junit.jar放在jdk的extension目录下<BR><BR>运行命令,结果如下图。<BR>java junit.swingui.TestRunner junit.samples.AllTests<BR><BR><BR><BR>3、Junit架构<BR>　　下面以Money这个类为例进行说明。<BR><BR>public class Money {<BR>&nbsp; &nbsp; private int fAmount;//余额<BR>&nbsp; &nbsp; private String fCurrency;//货币类型<BR><BR>&nbsp; &nbsp; public Money(int amount, String currency) {<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;fAmount= amount;<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;fCurrency= currency;<BR>&nbsp; &nbsp; }<BR><BR>&nbsp; &nbsp; public int amount() {<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;return fAmount;<BR>&nbsp; &nbsp; }<BR><BR>&nbsp; &nbsp; public String currency() {<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;return fCurrency;<BR>&nbsp; &nbsp; }<BR>&nbsp; &nbsp; <BR>&nbsp; &nbsp; public Money add(Money m) {//加钱<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;return new Money(amount()+m.amount(), currency());<BR>&nbsp; &nbsp; }<BR>&nbsp; &nbsp; <BR>&nbsp; &nbsp; public boolean equals(Object anObject) {//判断钱数是否相等<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;if (anObject instanceof Money) {<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;Money aMoney= (Money)anObject;<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;return aMoney.currency().equals(currency())<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; &amp;&amp; amount() == aMoney.amount();<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;}<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;return false;<BR>&nbsp; &nbsp; }&nbsp; &nbsp; <BR>}<BR><BR><BR>　　Junit本身是围绕着两个设计模式来设计的：命令模式和集成模式.<BR><BR>命令模式<BR>　　利用TestCase定义一个子类，在这个子类中生成一个被测试的对象，编写代码检测某个方法被调用后对象的状态与预期的状态是否一致，进而断言程序代码有没有bug。<BR>　　当这个子类要测试不只一个方法的实现代码时，可以先建立测试基础，让这些测试在同一个基础上运行，一方面可以减少每个测试的初始化，而且可以测试这些不同方法之间的联系。<BR>　　例如，我们要测试Money的Add方法，可以如下:<BR>public class MoneyTest extends TestCase { //TestCase的子类<BR>&nbsp; &nbsp; public void testAdd() { //把测试代码放在testAdd中<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;Money m12CHF= new Money(12, "CHF");&nbsp;&nbsp;//本行和下一行进行一些初始化<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;Money m14CHF= new Money(14, "CHF");&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;Money expected= new Money(26, "CHF");//预期的结果<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;Money result= m12CHF.add(m14CHF);&nbsp; &nbsp; //运行被测试的方法<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;Assert.assertTrue(expected.equals(result));&nbsp; &nbsp;&nbsp;&nbsp;//判断运行结果是否与预期的相同<BR>&nbsp; &nbsp; }<BR>}<BR><BR>　　如果测试一下equals方法，用类似的代码，如下：<BR>public class MoneyTest extends TestCase { //TestCase的子类<BR>&nbsp; &nbsp; public void testEquals() { //把测试代码放在testEquals中<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;Money m12CHF= new Money(12, "CHF"); //本行和下一行进行一些初始化<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;Money m14CHF= new Money(14, "CHF");<BR><BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;Assert.assertTrue(!m12CHF.equals(null));//进行不同情况的测试<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;Assert.assertEquals(m12CHF, m12CHF);<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;Assert.assertEquals(m12CHF, new Money(12, "CHF")); // (1)<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;Assert.assertTrue(!m12CHF.equals(m14CHF));<BR>&nbsp; &nbsp; }<BR>}<BR><BR><BR>　　当要同时进行测试Add和equals方法时，可以将它们的各自的初始化工作，合并到一起进行，形成测试基础,用setUp初始化，用tearDown清除。如下：<BR>public class MoneyTest extends TestCase {//TestCase的子类<BR>&nbsp; &nbsp; private Money f12CHF;//提取公用的对象<BR>&nbsp; &nbsp; private Money f14CHF;&nbsp; &nbsp;<BR><BR>&nbsp; &nbsp; protected void setUp() {//初始化公用对象<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;f12CHF= new Money(12, "CHF");<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;f14CHF= new Money(14, "CHF");<BR>&nbsp; &nbsp; }<BR>&nbsp; &nbsp; public void testEquals() {//测试equals方法的正确性<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;Assert.assertTrue(!f12CHF.equals(null));<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;Assert.assertEquals(f12CHF, f12CHF);<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;Assert.assertEquals(f12CHF, new Money(12, "CHF"));<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;Assert.assertTrue(!f12CHF.equals(f14CHF));<BR>&nbsp; &nbsp; }<BR>&nbsp; &nbsp; <BR>&nbsp; &nbsp; public void testSimpleAdd() {//测试add方法的正确性<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;Money expected= new Money(26, "CHF");<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;Money result= f12CHF.add(f14CHF);<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;Assert.assertTrue(expected.equals(result));<BR>&nbsp; &nbsp; }<BR>}<BR><BR><BR>　　将以上三个中的任一个TestCase子类代码保存到名为MoneyTest.java的文件里，并在文件首行增加<BR>import junit.framework.*;<BR>，都是可以运行的。关于Junit运行的问题很有意思，下面单独说明。<BR>　　上面为解释概念“测试基础(fixture)”，引入了两个对两个方法的测试。命令模式与集成模式的本质区别是，前者一次只运行一个测试。<BR><BR>集成模式<BR>　　利用TestSuite可以将一个TestCase子类中所有test***()方法包含进来一起运行，还可将TestSuite子类也包含进来，从而行成了一种等级关系。可以把TestSuite视为一个容器，可以盛放TestCase中的test***()方法，它自己也可以嵌套。这种体系架构，非常类似于现实中程序一步步开发一步步集成的现况。<BR>　　对上面的例子，有代码如下：<BR>public class MoneyTest extends TestCase {//TestCase的子类<BR>&nbsp; &nbsp; ....<BR>&nbsp; &nbsp; public static Test suite() {//静态Test<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;TestSuite suite= new TestSuite();//生成一个TestSuite<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;suite.addTest(new MoneyTest("testEquals")); //加入测试方法<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;suite.addTest(new MoneyTest("testSimpleAdd"));<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;return suite;<BR>&nbsp; &nbsp; }<BR>}<BR><BR>　　从Junit2.0开始，有列简捷的方法:<BR>public class MoneyTest extends TestCase {//TestCase的子类<BR>&nbsp; &nbsp; ....<BR>&nbsp; &nbsp; public static Test suite() {静态Test<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;return new TestSuite(MoneyTest.class); //以类为参数<BR>&nbsp; &nbsp; }<BR>}<BR><BR>　　TestSuite见嵌套的例子，在后面应用案例中有。<BR>　　<BR><BR>4、测试代码的运行<BR>　　先说最常用的集成模式。<BR>　　测试代码写好以后，可以相应的类中写main方法，用java命令直接运行；也可以不写main方法，用Junit提供的运行器运行。Junit提供了textui,awtui和swingui三种运行器。<BR>　　以前面第2步中的AllTests运行为例，可有四种：<BR><BR>java junit.textui.TestRunner junit.samples.AllTests<BR>java junit.awtui.TestRunner junit.samples.AllTests<BR>java junit.swingui.TestRunner junit.samples.AllTests<BR>java junit.samples.AllTests<BR><BR>　　main方法中一般也都是简单地用Runner调用suite()，当没有main时，TestRunner自己以运行的类为参数生成了一个TestSuite.<BR>　　<BR>　　对于命令模式的运行，有两种方法。<BR><BR>静态方法<BR><BR>TestCase test= new MoneyTest("simple add") {<BR>public void runTest() {<BR>testSimpleAdd();<BR>}<BR>};<BR><BR><BR>动态方法<BR><BR>TestCase test= new MoneyTest("testSimpleAdd");<BR><BR>　　我试了一下，好象有问题，哪位朋友成功了，请指点我一下。确实可以。<BR><BR>import junit.framework.*;<BR><BR>public class MoneyTest extends TestCase {//TestCase的子类<BR>&nbsp; &nbsp; private Money f12CHF;//提取公用的对象<BR>&nbsp; &nbsp; private Money f14CHF;&nbsp; &nbsp;<BR>&nbsp; &nbsp; public MoneyTest(String name){<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;super(name);<BR>&nbsp; &nbsp; }<BR>&nbsp; &nbsp; protected void setUp() {//初始化公用对象<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;f12CHF= new Money(12, "CHF");<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;f14CHF= new Money(14, "CHF");<BR>&nbsp; &nbsp; }<BR>&nbsp; &nbsp; public void testEquals() {//测试equals方法的正确性<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;Assert.assertTrue(!f12CHF.equals(null));<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;Assert.assertEquals(f12CHF, f12CHF);<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;Assert.assertEquals(f12CHF, new Money(12, "CHF"));<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;Assert.assertTrue(!f12CHF.equals(f14CHF));<BR>&nbsp; &nbsp; }<BR>&nbsp; &nbsp; <BR>&nbsp; &nbsp; public void testAdd() {//测试add方法的正确性<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;Money expected= new Money(26, "CHF");<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;Money result= f12CHF.add(f14CHF);<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;Assert.assertTrue(expected.equals(result));<BR>&nbsp; &nbsp; }<BR>//&nbsp; &nbsp; public static void main(String[] args) {<BR>//&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;TestCase test=new MoneyTest("simple add") {<BR>//&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; public void runTest() {<BR>//&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;testAdd();<BR>//&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; }<BR>//&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;};<BR>//&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;junit.textui.TestRunner.run(test);<BR>//&nbsp; &nbsp; }<BR>&nbsp; &nbsp; public static void main(String[] args) {<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;TestCase test=new MoneyTest("testAdd");<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;junit.textui.TestRunner.run(test);<BR>&nbsp; &nbsp; }<BR>}<BR><BR><BR>再给一个静态方法用集成测试的例子：<BR>public static Test suite() {<BR>&nbsp; &nbsp; TestSuite suite= new TestSuite();<BR>&nbsp; &nbsp; suite.addTest(<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;new testCar("getWheels") {<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;protected void runTest() { testGetWheels(); }<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;}<BR>&nbsp; &nbsp; );<BR><BR>&nbsp; &nbsp; suite.addTest(<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;new testCar("getSeats") {<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;protected void runTest() { testGetSeats(); }<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;}<BR>&nbsp; &nbsp; );<BR>&nbsp; &nbsp; return suite;<BR>}<BR><BR><BR>5、应用案例<BR><BR><BR>Junit Primer例程，运行如下：<BR>java com.hedong.JunitLearning.Primer.ShoppingCartTest<BR><BR><BR>Ant+Junit+Mailto实现自动编译、调试并发送结果的build.xml<BR><BR>JUnit实施,写得很棒，理解也深刻。例程运行如下：<BR>java com.hedong.JunitLearning.car.testCarNoJunit<BR>java junit.swingui.TestRunner com.hedong.JunitLearning.car.testCar<BR><BR><BR>Junit与log4j结合，阿菜的例程运行：<BR>cd acai<BR>ant junit<BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR>6、一些问题<BR>　　有人在实践基础上总结出一些非常有价值的使用技巧，我没有经过一一“测试”，暂列在此。<BR><BR>不要用TestCase的构造函数初始化Fixture，而要用setUp()和tearDown()方法。<BR><BR>不要依赖或假定测试运行的顺序，因为JUnit利用Vector保存测试方法。所以不同的平台会按不同的顺序从Vector中取出测试方法。不知3.8中是不是还是如此，不过它提供的例子有一个是指定用VectorSuite的，如果不指定呢？<BR><BR>避免编写有副作用的TestCase。例如：如果随后的测试依赖于某些特定的交易数据，就不要提交交易数据。简单的回滚就可以了。<BR><BR>当继承一个测试类时，记得调用父类的setUp()和tearDown()方法。<BR><BR>将测试代码和工作代码放在一起，一边同步编译和更新。（使用Ant中有支持junit的task.）<BR><BR>测试类和测试方法应该有一致的命名方案。如在工作类名前加上test从而形成测试类名。<BR><BR>确保测试与时间无关，不要依赖使用过期的数据进行测试。导致在随后的维护过程中很难重现测试。<BR><BR>如果你编写的软件面向国际市场，编写测试时要考虑国际化的因素。不要仅用母语的Locale进行测试。<BR><BR>尽可能地利用JUnit提供地assert/fail方法以及异常处理的方法，可以使代码更为简洁。<BR><BR>测试要尽可能地小，执行速度快。<BR><BR>把测试程序建立在与被测对象相同的包中<BR><BR>在你的原始代码目录中避免测试码出现，可在一个源码镜像目录中放测试码<BR><BR>在自己的应用程序包中包含一个TestSuite测试类<BR><BR><BR><BR><BR><BR>7、相关资源下载<BR>以下jar包，我只是做了打包、编译和调试的工作，供下载学习之用，相关的权利属于原作者。<BR><BR>可运行例程.jar<BR><BR>Build.xml<BR><BR>阿菜的例程<BR><BR>Junit API 汉译(pdf)<BR><BR><BR>8、未完成的任务<BR><BR><BR>httpunit<BR><BR>cactus<BR><BR>将Junit用链接池测试<BR><BR><BR>主要参考文献：<BR><BR><BR><BR>JUnit入門<BR>[url]http://www.dotspace.twmail.org/Test/JUnit_Primer.htm[/url]<BR><BR>怎样使用Junit Framework进行单元测试的编写<BR>[url]http://www.chinaunix.net/bbsjh/14/546.html[/url]<BR><BR>Ant+Junit+Log4J+CVS进行XP模式开发的建立<BR>[url]http://ejb.cn/modules/tutorials/printpage.php?tid=4[/url]<BR><BR>用HttpUnit测试Web应用程序<BR>[url]http://www.zdnet.com.cn/developer/code/story/0[/url],2000081534,39033726,00.htm<BR><BR>有没有用过Cactus的，Web层的测试是Cactus还是JUnit？<BR>[url]http://www.jdon.com/jive/thread.jsp?forum=16&amp;thread=9156[/url]<BR><BR>Ant+junit的测试自动化 biggie（原作）<BR>[url]http://www.csdn.net/Develop/article/19%5C19748.shtm[/url]<BR><BR>JUnit实施<BR>[url]http://www.neweasier.com/article/2002-08-07/1028723459.html[/url]<BR><BR>JUnitTest Infected: Programmers Love Writing Tests<BR>[url]http://junit.sourceforge.net/doc/testinfected/testing.htm[/url]<BR><BR>JUnit Cookbook<BR>[url]http://junit.sourceforge.net/doc/cookbook/cookbook.htm[/url]<BR><BR>JUnit Primer<BR>[url]http://www.itu.dk/~lthorup/JUnitPrimer.html[/url]<BR><BR>IBM DevelopWorks<BR>[url]http://www-106.ibm.com/search/searchResults.jsp?query=junit&amp;searchScope=dW&amp;[/url]<BR>searchType=1&amp;searchSite=dWChina&amp;pageLang=zh&amp;langEncoding=gb2312&amp;Search.x=0&amp;<BR>Search.y=0&amp;Search=Search<img src ="http://www.blogjava.net/fjq639/aggbug/24833.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fjq639/" target="_blank">黑石</a> 2005-12-20 18:02 <a href="http://www.blogjava.net/fjq639/archive/2005/12/20/24833.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JDOM使用详解及实例[转]</title><link>http://www.blogjava.net/fjq639/archive/2005/12/20/24813.html</link><dc:creator>黑石</dc:creator><author>黑石</author><pubDate>Tue, 20 Dec 2005 08:20:00 GMT</pubDate><guid>http://www.blogjava.net/fjq639/archive/2005/12/20/24813.html</guid><wfw:comment>http://www.blogjava.net/fjq639/comments/24813.html</wfw:comment><comments>http://www.blogjava.net/fjq639/archive/2005/12/20/24813.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/fjq639/comments/commentRss/24813.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fjq639/services/trackbacks/24813.html</trackback:ping><description><![CDATA[<DIV id=wrapper>
<DIV id=innerWrapper>
<DIV id=mainWrapper>
<DIV id=articleContent>
<DIV id=articleInnerContent>
<DIV class=item>
<DIV class=item-title>
<H3>官方网站:<A href="http://www.jdom.org/downloads/index.html">http://www.jdom.org/downloads/index.html</A></H3>
<DIV class=clear></DIV></DIV>
<DIV class=item-top></DIV>
<DIV class=item-body>
<DIV class=item-content>
<P>一、JDOM简介</P>
<P>JDOM是一个开源项目，它基于树型结构，利用纯JAVA的技术对XML文档实现解析、生成、序列化以及多种操作。</P>
<P>JDOM直接为JAVA编程服务。它利用更为强有力的JAVA语言的诸多特性（方法重载、集合概念以及映射），把SAX和DOM的功能有效地结合起来。</P>
<P>在使用设计上尽可能地隐藏原来使用XML过程中的复杂性。利用JDOM处理XML文档将是一件轻松、简单的事。</P>
<P>JDOM在2000年的春天被BrettMcLaughlin和JasonHunter开发出来，以弥补DOM及SAX在实际应用当中的不足之处。</P>
<P>这些不足之处主要在于SAX没有文档修改、随机访问以及输出的功能，而对于DOM来说，JAVA程序员在使用时来用起来总觉得不太方便。</P>
<P>DOM的缺点主要是来自于由于Dom是一个接口定义语言（IDL）,它的任务是在不同语言实现中的一个最低的通用标准，并不是为JAVA特别设计的。JDOM的最新版本为JDOMBeta9。最近JDOM被收录到JSR-102内，这标志着JDOM成为了JAVA平台组成的一部分。</P>
<P>二、JDOM包概览</P>
<P>JDOM是由以下几个包组成的<BR>org.jdom&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;包含了所有的xml文档要素的java类</P>
<P>&nbsp;</P>
<P>org.jdom.adapters&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;包含了与dom适配的java类</P>
<P>&nbsp;</P>
<P>org.jdom.filter&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;包含了xml文档的过滤器类</P>
<P>&nbsp;</P>
<P>org.jdom.input&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;包含了读取xml文档的类</P>
<P>&nbsp;</P>
<P>org.jdom.output&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;包含了写入xml文档的类</P>
<P>&nbsp;</P>
<P>org.jdom.transform&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;包含了将jdomxml文档接口转换为其他xml文档接口</P>
<P>&nbsp;</P>
<P>org.jdom.xpath&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;包含了对xml文档xpath操作的类三、JDOM类说明</P>
<P>1、org.JDOM这个包里的类是你J解析xml文件后所要用到的所有数据类型。</P>
<P>Attribute</P>
<P>CDATA</P>
<P>Coment</P>
<P>DocType</P>
<P>Document</P>
<P>Element</P>
<P>EntityRef</P>
<P>Namespace</P>
<P>ProscessingInstruction</P>
<P>Text</P>
<P>2、org.JDOM.transform在涉及xslt格式转换时应使用下面的2个类</P>
<P>JDOMSource</P>
<P>JDOMResult</P>
<P>org.JDOM.input</P>
<P>3、输入类，一般用于文档的创建工作</P>
<P>SAXBuilder</P>
<P>DOMBuilder</P>
<P>ResultSetBuilder</P>
<P>org.JDOM.output</P>
<P>4、输出类，用于文档转换输出</P>
<P>XMLOutputter</P>
<P>SAXOutputter</P>
<P>DomOutputter</P>
<P>JTreeOutputter</P>
<P>使用前注意事项：</P>
<P>1.JDOM对于JAXP以及TRax的支持</P>
<P>JDOM支持JAXP1.1：你可以在程序中使用任何的parser工具类,默认情况下是JAXP的parser。</P>
<P>制定特别的parser可用如下形式</P>
<P>SAXBuilderparser</P>
<P>&nbsp;=newSAXBuilder("org.apache.crimson.parser.XMLReaderImpl");</P>
<P>&nbsp;Documentdoc=parser.build("http://www.cafeconleche.org/");</P>
<P>&nbsp;//workwiththedocument...</P>
<P>JDOM也支持TRaX：XSLT可通过JDOMSource以及JDOMResult类来转换（参见以后章节）</P>
<P>2.注意在JDOM里文档（Document）类由org.JDOM.Document来表示。这要与org.w3c.dom中的Document区别开，这2种格式如何转换在后面会说明。</P>
<P>以下如无特指均指JDOM里的Document。</P>
<P>四、JDOM主要使用方法</P>
<P>1.Ducument类</P>
<P>(1)Document的操作方法：</P>
<P>Elementroot=newElement("GREETING");</P>
<P>Documentdoc=newDocument(root);</P>
<P>root.setText("HelloJDOM!");</P>
<P>或者简单的使用Documentdoc=newDocument(newElement("GREETING").setText("HelloJDOM!t"));</P>
<P>这点和DOM不同。Dom则需要更为复杂的代码，如下：</P>
<P>DocumentBuilderFactoryfactory=DocumentBuilderFactory.newInstance();</P>
<P>DocumentBuilderbuilder=factory.newDocumentBuilder();</P>
<P>Documentdoc=builder.newDocument();</P>
<P>Elementroot=doc.createElement("root");</P>
<P>Texttext=doc.createText("Thisistheroot");</P>
<P>root.appendChild(text);</P>
<P>doc.appendChild(root);</P>
<P>注意事项：JDOM不允许同一个节点同时被2个或多个文档相关联，要在第2个文档中使用原来老文档中的节点的话。首先需要使用detach()把这个节点分开来。</P>
<P>(2)从文件、流、系统ID、URL得到Document对象：</P>
<P>DOMBuilderbuilder=newDOMBuilder();</P>
<P>Documentdoc=builder.build(newFile("jdom_test.xml"));</P>
<P>SAXBuilderbuilder=newSAXBuilder();</P>
<P>Documentdoc=builder.build(url);</P>
<P>在新版本中DOMBuilder已经Deprecated掉DOMBuilder.builder(url)，用SAX效率会比较快。</P>
<P>这里举一个小例子，为了简单起见，使用String对象直接作为xml数据源：</P>
<P>&nbsp;publicjdomTest(){</P>
<P>&nbsp;&nbsp;&nbsp;StringtextXml=null;</P>
<P>&nbsp;&nbsp;&nbsp;textXml="&lt;note&gt;";</P>
<P>&nbsp;&nbsp;&nbsp;textXml=textXml+</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"&lt;to&gt;aaa&lt;/to&gt;&lt;from&gt;bbb&lt;/from&gt;&lt;heading&gt;ccc&lt;/heading&gt;&lt;body&gt;ddd&lt;/body&gt;";</P>
<P>&nbsp;&nbsp;&nbsp;textXml=textXml+"&lt;/note&gt;";</P>
<P>&nbsp;&nbsp;&nbsp;SAXBuilderbuilder=newSAXBuilder();</P>
<P>&nbsp;&nbsp;&nbsp;Documentdoc=null;</P>
<P>&nbsp;&nbsp;&nbsp;Readerin=newStringReader(textXml);</P>
<P>&nbsp;&nbsp;&nbsp;try{</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;doc=builder.build(in);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Elementroot=doc.getRootElement();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Listls=root.getChildren();//注意此处取出的是root节点下面的一层的Element集合</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(Iteratoriter=ls.iterator();iter.hasNext();){</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Elementel=(Element)iter.next();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(el.getName().equals("to")){</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(el.getText());</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</P>
<P>&nbsp;&nbsp;&nbsp;}</P>
<P>&nbsp;&nbsp;&nbsp;catch(IOExceptionex){</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ex.printStackTrace();</P>
<P>&nbsp;&nbsp;&nbsp;}</P>
<P>&nbsp;&nbsp;&nbsp;catch(JDOMExceptionex){</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ex.printStackTrace();</P>
<P>&nbsp;&nbsp;&nbsp;}</P>
<P>&nbsp;}</P>
<P>(3)DOM的document和JDOM的Document之间的相互转换使用方法，简单！</P>
<P>DOMBuilderbuilder=newDOMBuilder();</P>
<P>org.jdom.DocumentjdomDocument=builder.build(domDocument);</P>
<P>DOMOutputterconverter=newDOMOutputter();//workwiththeJDOMdocument…</P>
<P>org.w3c.dom.DocumentdomDocument=converter.output(jdomDocument);</P>
<P>//workwiththeDOMdocument…</P>
<P>2.XML文档输出</P>
<P>XMLOutPutter类：</P>
<P>JDOM的输出非常灵活,支持很多种io格式以及风格的输出</P>
<P>Documentdoc=newDocument(...);</P>
<P>XMLOutputteroutp=newXMLOutputter();</P>
<P>outp.output(doc,fileOutputStream);//Rawoutput</P>
<P>outp.setTextTrim(true);//Compressedoutput</P>
<P>outp.output(doc,socket.getOutputStream());</P>
<P>outp.setIndent("");//Prettyoutput</P>
<P>outp.setNewlines(true);</P>
<P>outp.output(doc,System.out);</P>
<P>详细请参阅最新的JDOMAPI手册</P>
<P>3.Element类：</P>
<P>(1)浏览Element树</P>
<P>Elementroot=doc.getRootElement();//获得根元素element</P>
<P>ListallChildren=root.getChildren();//获得所有子元素的一个list</P>
<P>ListnamedChildren=root.getChildren("name");//获得指定名称子元素的list</P>
<P>Elementchild=root.getChild("name");//获得指定名称的第一个子元素</P>
<P>JDOM给了我们很多很灵活的使用方法来管理子元素（这里的List是java.util.List）</P>
<P>ListallChildren=root.getChildren();</P>
<P>allChildren.remove(3);//删除第四个子元素</P>
<P>allChildren.removeAll(root.getChildren("jack"));//删除叫“jack”的子元素</P>
<P>root.removeChildren("jack");//便捷写法</P>
<P>allChildren.add(newElement("jane"));//加入</P>
<P>root.addContent(newElement("jane"));//便捷写法</P>
<P>allChildren.add(0,newElement("first"));</P>
<P>(2)移动Elements:</P>
<P>在JDOM里很简单</P>
<P>Elementmovable=newElement("movable");</P>
<P>parent1.addContent(movable);//place</P>
<P>parent1.removeContent(movable);//remove</P>
<P>parent2.addContent(movable);//add</P>
<P>在Dom里</P>
<P>Elementmovable=doc1.createElement("movable");</P>
<P>parent1.appendChild(movable);//place</P>
<P>parent1.removeChild(movable);//remove</P>
<P>parent2.appendChild(movable);//出错!</P>
<P>补充：纠错性</P>
<P>JDOM的Element构造函数（以及它的其他函数）会检查element是否合法。</P>
<P>而它的add/remove方法会检查树结构，检查内容如下：</P>
<P>1.在任何树中是否有回环节点</P>
<P>2.是否只有一个根节点</P>
<P>3.是否有一致的命名空间（Namespaces）</P>
<P>(3)Element的text内容读取</P>
<P>&lt;description&gt;</P>
<P>Acooldemo</P>
<P>&lt;/description&gt;</P>
<P>//Thetextisdirectlyavailable</P>
<P>//Returns"\nAcooldemo\n"</P>
<P>Stringdesc=element.getText();</P>
<P>//There'saconvenientshortcut</P>
<P>//Returns"Acooldemo"</P>
<P>Stringdesc=element.getTextTrim();</P>
<P>(4)Elment内容修改</P>
<P>element.setText("Anewdescription");</P>
<P>3.可正确解释特殊字符</P>
<P>element.setText("&lt;xml&gt;content");</P>
<P>4.CDATA的数据写入、读出</P>
<P>element.addContent(newCDATA("&lt;xml&gt;content"));</P>
<P>StringnoDifference=element.getText();</P>
<P>混合内容</P>
<P>element可能包含很多种内容，比如说</P>
<P>&lt;table&gt;</P>
<P>&lt;!--Somecomment--&gt;</P>
<P>Sometext</P>
<P>&lt;tr&gt;Somechildelement&lt;/tr&gt;</P>
<P>&lt;/table&gt;</P>
<P>取table的子元素tr</P>
<P>Stringtext=table.getTextTrim();</P>
<P>Elementtr=table.getChild("tr");</P>
<P>也可使用另外一个比较简单的方法</P>
<P>ListmixedCo=table.getContent();</P>
<P>Iteratoritr=mixedCo.iterator();</P>
<P>while(itr.hasNext()){</P>
<P>Objecto=i.next();</P>
<P>if(oinstanceofComment){...}</P>
<P>//这里可以写成Comment,Element,Text,CDATA,ProcessingInstruction,或者是EntityRef的类型</P>
<P>}</P>
<P>//现在移除Comment,注意这里游标应为1。这是由于回车键也被解析成Text类的缘故,所以Comment项应为1。</P>
<P>mixedCo.remove(1);</P>
<P>4.Attribute类</P>
<P>&lt;tablewidth="100%"border="0"&gt;&lt;/table&gt;</P>
<P>Stringwidth=table.getAttributeValue("width");//获得attribute</P>
<P>intborder=table.getAttribute("width").getIntValue();</P>
<P>table.setAttribute("vspace","0");//设置attribute</P>
<P>table.removeAttribute("vspace");//删除一个或全部attribute</P>
<P>table.getAttributes().clear();</P>
<P>5.处理指令(ProcessingInstructions)操作</P>
<P>一个Pls的例子</P>
<P>&lt;?br?&gt;</P>
<P>&lt;?cocoon-processtype="xslt"?&gt;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;目标&nbsp;&nbsp;&nbsp;&nbsp;数据</P>
<P>处理目标名称(Target)</P>
<P>Stringtarget=pi.getTarget();</P>
<P>获得所有数据（data），在目标（target）以后的所有数据都会被返回。</P>
<P>Stringdata=pi.getData();</P>
<P>Stringtype=pi.getValue("type");获得指定属性的数据</P>
<P>Listls=pi.getNames();获得所有属性的名称</P>
<P>6.命名空间操作</P>
<P>&lt;xhtml:html</P>
<P>&nbsp;xmlns:xhtml="http://www.w3.org/1999/xhtml"&gt;</P>
<P>&lt;xhtml:title&gt;HomePage&lt;/xhtml:title&gt;</P>
<P>&lt;/xhtml:html&gt;</P>
<P>Namespacexhtml=Namespace.getNamespace("xhtml","http://www.w3.org/1999/xhtml");</P>
<P>Listkids=html.getChildren("title",xhtml);</P>
<P>Elementkid=html.getChild("title",xhtml);</P>
<P>kid.addContent(newElement("table",xhtml));</P>
<P>7.XSLT格式转换</P>
<P>使用以下函数可对XSLT转换</P>
<P>最后如果你需要使用w3c的Document则需要转换一下。</P>
<P>publicstaticDocumenttransform(Stringstylesheet，Documentin)</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throwsJDOMException{</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;try{</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Transformertransformer=TransformerFactory.newInstance()</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.newTransformer(newStreamSource(stylesheet));</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JDOMResultout=newJDOMResult();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;transformer.transform(newJDOMSource(in),out);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;returnout.getDeocument();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;}</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;catch(TransformerExceptione){</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;thrownewJDOMException("XSLTTrandformationfailed",e);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;}</P>
<P>&nbsp;&nbsp;}</P>
<P>五、用例:</P>
<P>1、生成xml文档：</P>
<P>&nbsp;</P>
<P>&nbsp;</P>
<P>publicclassWriteXML{</P>
<P>&nbsp;&nbsp;&nbsp;publicvoidBuildXML()throwsException{</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Elementroot,student,number,name,age;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;root=newElement("student-info");//生成根元素：student-info</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;student=newElement("student");//生成元素：student(number,name,age)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;number=newElement("number");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name=newElement("name");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;age=newElement("age");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Documentdoc=newDocument(root);//将根元素植入文档doc中</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;number.setText("001");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name.setText("lnman");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;age.setText("24");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;student.addContent(number);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;student.addContent(name);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;student.addContent(age);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;root.addContent(student);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Formatformat=Format.getCompactFormat();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;format.setEncoding("gb2312");//设置xml文件的字符为gb2312</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;format.setIndent("&nbsp;&nbsp;&nbsp;");//设置xml文件的缩进为4个空格</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;XMLOutputterXMLOut=newXMLOutputter(format);//元素后换行一层元素缩四格</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;XMLOut.output(doc,newFileOutputStream("studentinfo.xml"));&nbsp;</P>
<P>}</P>
<P>&nbsp;&nbsp;&nbsp;publicstaticvoidmain(String[]args)throwsException{</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WriteXMLw=newWriteXML();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("NowwebuildanXMLdocument.....");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;w.BuildXML();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("finished!");</P>
<P>}</P>
<P>}</P>
<P>生成的xml文档为：</P>
<P>&lt;?xmlversion="1.0"encoding="gb2312"?&gt;</P>
<P>&lt;student-info&gt;</P>
<P>&nbsp;&nbsp;&nbsp;&lt;student&gt;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;number&gt;001&lt;/number&gt;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;name&gt;lnman&lt;/name&gt;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;age&gt;24&lt;/age&gt;</P>
<P>&nbsp;&nbsp;&nbsp;&lt;/student&gt;</P>
<P>&lt;/student-info&gt;</P>
<P>&nbsp;</P>
<P>&nbsp;</P>
<P>创建XML文档2：</P>
<P>&nbsp;publicclassCreateXML{</P>
<P>&nbsp;publicvoidCreate(){</P>
<P>&nbsp;&nbsp;try{</P>
<P>&nbsp;&nbsp;&nbsp;Documentdoc=newDocument();&nbsp;&nbsp;</P>
<P>&nbsp;&nbsp;&nbsp;ProcessingInstructionpi=newProcessingInstruction("xml-stylesheet","type="text/xsl"href="test.xsl"");</P>
<P>&nbsp;&nbsp;&nbsp;doc.addContent(pi);&nbsp;&nbsp;&nbsp;</P>
<P>&nbsp;&nbsp;&nbsp;Namespacens=Namespace.getNamespace("http://www.bromon.org");</P>
<P>&nbsp;&nbsp;&nbsp;Namespacens2=Namespace.getNamespace("other","http://www.w3c.org");</P>
<P>&nbsp;&nbsp;&nbsp;Elementroot=newElement("根元素",ns);</P>
<P>&nbsp;&nbsp;&nbsp;root.addNamespaceDeclaration(ns2);</P>
<P>&nbsp;&nbsp;&nbsp;doc.setRootElement(root);</P>
<P>&nbsp;&nbsp;&nbsp;Elementel1=newElement("元素一");</P>
<P>&nbsp;&nbsp;&nbsp;el1.setAttribute("属性","属性一");&nbsp;&nbsp;&nbsp;</P>
<P>&nbsp;&nbsp;&nbsp;Texttext1=newText("元素值");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Elementem=newElement("元素二").addContent("第二个元素");</P>
<P>&nbsp;&nbsp;&nbsp;el1.addContent(text1);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;el1.addContent(em);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Elementel2=newElement("元素三").addContent("第三个元素");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;root.addContent(el1);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;root.addContent(el2);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//缩进四个空格,自动换行,gb2312编码</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;XMLOutputteroutputter=newXMLOutputter("&nbsp;",true,"GB2312");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;outputter.output(doc,newFileWriter("test.xml"));</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}catch(Exceptione)&nbsp;{</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(e);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;publicstaticvoidmain(Stringargs[]){</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;newCreateXML().Create();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;</P>
<P>&nbsp;}</P>
<P>2、读取xml文档的例子：</P>
<P>importorg.jdom.output.*;</P>
<P>importorg.jdom.input.*;</P>
<P>importorg.jdom.*;</P>
<P>importjava.io.*;</P>
<P>importjava.util.*;</P>
<P>publicclassReadXML{</P>
<P>&nbsp;&nbsp;&nbsp;publicstaticvoidmain(String[]args)throwsException{</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SAXBuilderbuilder=newSAXBuilder();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Documentread_doc=builder.build("studentinfo.xml");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Elementstu=read_doc.getRootElement();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Listlist=stu.getChildren("student");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(inti=0;i&lt;list.size();i++){</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Elemente=(Element)list.get(i);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Stringstr_number=e.getChildText("number");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Stringstr_name=e.getChildText("name");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Stringstr_age=e.getChildText("age");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("---------STUDENT--------------");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("NUMBER:"+str_number);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("NAME:"+str_name);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("AGE:"+str_age);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("------------------------------");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</P>
<P>}</P>
<P>3、DTD验证的：</P>
<P>&nbsp;publicclassXMLWithDTD{</P>
<P>&nbsp;publicvoidvalidate()&nbsp;{</P>
<P>&nbsp;&nbsp;try{</P>
<P>&nbsp;&nbsp;&nbsp;SAXBuilderbuilder=newSAXBuilder(true);</P>
<P>&nbsp;&nbsp;&nbsp;builder.setFeature("http://xml.org/sax/features/validation";,true);</P>
<P>&nbsp;&nbsp;&nbsp;Documentdoc=builder.build(newFileReader("author.xml"));&nbsp;&nbsp;&nbsp;</P>
<P>&nbsp;&nbsp;&nbsp;System.out.println("搞掂");</P>
<P>&nbsp;&nbsp;&nbsp;XMLOutputteroutputter=newXMLOutputter();</P>
<P>&nbsp;&nbsp;&nbsp;outputter.output(doc,System.out);</P>
<P>&nbsp;&nbsp;}catch(Exceptione){</P>
<P>&nbsp;&nbsp;&nbsp;System.out.println(e);</P>
<P>&nbsp;&nbsp;}&nbsp;&nbsp;</P>
<P>&nbsp;}</P>
<P>&nbsp;publicstaticvoidmain(Stringargs[]){</P>
<P>&nbsp;&nbsp;newXMLWithDTD().validate();</P>
<P>&nbsp;}&nbsp;</P>
<P>&nbsp;}</P>
<P>&nbsp;需要说明的是，这个程序没有指明使用哪个DTD文件。DTD文件的位置是在XML中指定的，而且DTD不支持命名空间，一个XML只能引用一个DTD，所以程序直接读取XML中指定的DTD，程序本身不用指定。不过这样一来，好象就只能使用外部式的DTD引用方式了？高人指点。</P>
<P>&nbsp;</P>
<P>&nbsp;</P>
<P>4、XMLSchema验证的：</P>
<P>&nbsp;publicclassXMLWithSchema{</P>
<P>&nbsp;Stringxml="test.xml";</P>
<P>&nbsp;Stringschema="test-schema.xml";</P>
<P>&nbsp;publicvoidvalidate(){</P>
<P>&nbsp;&nbsp;try{</P>
<P>&nbsp;&nbsp;&nbsp;SAXBuilderbuilder=newSAXBuilder(true);</P>
<P>&nbsp;&nbsp;&nbsp;//指定约束方式为XMLschema</P>
<P>&nbsp;&nbsp;&nbsp;builder.setFeature("http://apache.org/xml/features/validation/schema";,&nbsp;true);</P>
<P>&nbsp;&nbsp;&nbsp;//导入schema文件</P>
<P>builder.setProperty("http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation";,schema);</P>
<P>&nbsp;&nbsp;&nbsp;Documentdoc=builder.build(newFileReader(xml));&nbsp;&nbsp;&nbsp;</P>
<P>&nbsp;&nbsp;&nbsp;System.out.println("搞掂");</P>
<P>&nbsp;&nbsp;&nbsp;XMLOutputteroutputter=newXMLOutputter();</P>
<P>&nbsp;&nbsp;&nbsp;outputter.output(doc,System.out);</P>
<P>&nbsp;&nbsp;}catch(Exceptione){</P>
<P>&nbsp;&nbsp;&nbsp;System.out.println("验证失败:"+e);</P>
<P>&nbsp;&nbsp;}&nbsp;</P>
<P>&nbsp;}</P>
<P>&nbsp;}</P>
<P>&nbsp;上面的程序就指出了要引入的XMLSchema文件的位置。</P>
<P>&nbsp;</P>
<P>&nbsp;</P>
<P>&nbsp;系统默认输出是UTF-8，这有可能导致出现乱码。</P>
<P>5、Xpath例子：</P>
<P>JDOM的关于XPATH的api在org.jdom.xpath这个包里。这个包下，有一个抽象类XPath.java和实现类JaxenXPath.java，使用时先用XPath类的静态方法newInstance(Stringxpath)得到XPath对象，然后调用它的selectNodes(Objectcontext)方法或selectSingleNode(Objectcontext)方法，前者根据xpath语句返回一组节点(List对象)；后者根据一个xpath语句返回符合条件的第一个节点(Object类型)。请看jdom-1.0自带的范例程序：</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;它分析在web.xml文件中的注册的servlet的个数及参数个数，并输出角色名。</P>
<P>web.xml文件：</P>
<P>&lt;?xmlversion="1.0"encoding="ISO-8859-1"?&gt;</P>
<P>&lt;!--</P>
<P>&lt;!DOCTYPEweb-app</P>
<P>&nbsp;&nbsp;&nbsp;PUBLIC"-//SunMicrosystems,Inc.//DTDWebApplication2.2//EN"</P>
<P>&nbsp;&nbsp;&nbsp;"http://java.sun.com/j2ee/dtds/web-app_2.2.dtd"&gt;</P>
<P>--&gt;</P>
<P>&lt;web-app&gt;</P>
<P>&nbsp;&nbsp;&nbsp;&lt;servlet&gt;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;servlet-name&gt;snoop&lt;/servlet-name&gt;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;servlet-class&gt;SnoopServlet&lt;/servlet-class&gt;</P>
<P>&nbsp;&nbsp;&nbsp;&lt;/servlet&gt;</P>
<P>&nbsp;&nbsp;&nbsp;&lt;servlet&gt;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;servlet-name&gt;file&lt;/servlet-name&gt;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;servlet-class&gt;ViewFile&lt;/servlet-class&gt;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;init-param&gt;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;param-name&gt;initial&lt;/param-name&gt;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;param-value&gt;1000&lt;/param-value&gt;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;description&gt;Theinitialvalueforthecounter&nbsp;&lt;!--optional--&gt;&lt;/description&gt;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/init-param&gt;</P>
<P>&nbsp;&nbsp;&nbsp;&lt;/servlet&gt;</P>
<P>&nbsp;&nbsp;&nbsp;&lt;servlet-mapping&gt;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;servlet-name&gt;mv&lt;/servlet-name&gt;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;url-pattern&gt;*.wm&lt;/url-pattern&gt;</P>
<P>&nbsp;&nbsp;&nbsp;&lt;/servlet-mapping&gt;</P>
<P>&nbsp;&nbsp;&nbsp;&lt;distributed/&gt;</P>
<P>&nbsp;&nbsp;&nbsp;&lt;security-role&gt;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;role-name&gt;manager&lt;/role-name&gt;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;role-name&gt;director&lt;/role-name&gt;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;role-name&gt;president&lt;/role-name&gt;</P>
<P>&nbsp;&nbsp;&nbsp;&lt;/security-role&gt;</P>
<P>&lt;/web-app&gt;</P>
<P>处理程序：</P>
<P>importjava.io.*;</P>
<P>importjava.util.*;&nbsp;</P>
<P>publicclassXPathReader{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</P>
<P>&nbsp;&nbsp;&nbsp;publicstaticvoidmain(String[]args)throwsIOException,JDOMException{</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(args.length!=1){</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.err.println("Usage:javaXPathReaderweb.xml");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Stringfilename=args[0];//从命令行输入web.xml</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PrintStreamout=System.out;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SAXBuilderbuilder=newSAXBuilder();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Documentdoc=builder.build(newFile(filename));//得到Document对象</P>
<P>&nbsp;</P>
<P>&nbsp;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//Printservletinformation</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;XPathservletPath=XPath.newInstance("//servlet");//,选择任意路径下servlet元素</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Listservlets=servletPath.selectNodes(doc);//返回所有的servlet元素。</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.println("ThisWARhas"+servlets.size()+"registeredservlets:");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Iteratori=servlets.iterator();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(i.hasNext()){//输出servlet信息</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Elementservlet=(Element)i.next();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.print("\t"+servlet.getChild("servlet-name")</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.getTextTrim()+</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"for"+servlet.getChild("servlet-class")</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.getTextTrim());</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ListinitParams=servlet.getChildren("init-param");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.println("(ithas"+initParams.size()+"initparams)");&nbsp;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//Printsecurityroleinformation</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;XPathrolePath=XPath.newInstance("//security-role/role-name/text()");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ListroleNames=rolePath.selectNodes(doc);//得到所有的角色名</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(roleNames.size()==0){</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.println("ThisWARcontainsnoroles");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}else{</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.println("ThisWARcontains"+roleNames.size()+"roles:");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i=roleNames.iterator();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(i.hasNext()){//输出角色名</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.println("\t"+((Text)i.next()).getTextTrim());</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</P>
<P>&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;</P>
<P>}</P>
<P>&nbsp;</P>
<P>&nbsp;</P>
<P>输出结果:</P>
<P>C:\java&gt;java&nbsp;&nbsp;XPathReaderweb.xml</P>
<P>ThisWARhas2registeredservlets:</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;snoopforSnoopServlet(ithas0initparams)</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fileforViewFile(ithas1initparams)</P>
<P>ThisWARcontains3roles:</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;manager</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;director</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;president</P>
<P>&nbsp;</P>
<P>&nbsp;</P>
<P>6、数据输入要用到XML文档要通过org.jdom.input包，反过来需要org.jdom.output。如前面所说，关是看API文档就能够使用。</P>
<P>我们的例子读入XML文件exampleA.xml，加入一条处理指令，修改第一本书的价格和作者，并添加一条属性，然后写入文件exampleB.xml：</P>
<P>//exampleA.xml</P>
<P>&lt;?xmlversion="1.0"encoding="GBK"?&gt;</P>
<P>&lt;bookList&gt;</P>
<P>&lt;book&gt;</P>
<P>&lt;name&gt;Java编程入门&lt;/name&gt;</P>
<P>&lt;author&gt;张三&lt;/author&gt;</P>
<P>&lt;publishDate&gt;2002-6-6&lt;/publishDate&gt;</P>
<P>&lt;price&gt;35.0&lt;/price&gt;</P>
<P>&lt;/book&gt;</P>
<P>&lt;book&gt;</P>
<P>&lt;name&gt;XML在Java中的应用&lt;/name&gt;</P>
<P>&lt;author&gt;李四&lt;/author&gt;</P>
<P>&lt;publishDate&gt;2002-9-16&lt;/publishDate&gt;</P>
<P>&lt;price&gt;92.0&lt;/price&gt;</P>
<P>&lt;/book&gt;</P>
<P>&lt;/bookList&gt;</P>
<P>//testJDOM.java</P>
<P>importorg.jdom.*;</P>
<P>importorg.jdom.output.*;</P>
<P>importorg.jdom.input.*;</P>
<P>importjava.io.*;</P>
<P>publicclassTestJDOM{</P>
<P>publicstaticvoidmain(Stringargs[])throwsException{</P>
<P>SAXBuildersb=newSAXBuilder();</P>
<P>//从文件构造一个Document，因为XML文件中已经指定了编码，所以这里不必了</P>
<P>Documentdoc=sb.build(newFileInputStream("exampleA.xml"));</P>
<P>ProcessingInstructionpi=newProcessingInstruction//加入一条处理指令</P>
<P>("xml-stylesheet","href=\"bookList.html.xsl\"type=\"text/xsl\"");</P>
<P>doc.addContent(pi);</P>
<P>Elementroot=doc.getRootElement();//得到根元素</P>
<P>java.util.Listbooks=root.getChildren();//得到根元素所有子元素的集合</P>
<P>Elementbook=(Element)books.get(0);//得到第一个book元素</P>
<P>//为第一本书添加一条属性</P>
<P>Attributea=newAttribute("hot","true");</P>
<P>book.setAttribute(a);</P>
<P>Elementauthor=book.getChild("author");//得到指定的字元素</P>
<P>author.setText("王五");//将作者改为王五</P>
<P>//或Textt=newText("王五");book.addContent(t);</P>
<P>Elementprice=book.getChild("price");//得到指定的字元素</P>
<P>//修改价格，比较郁闷的是我们必须自己转换数据类型，而这正是JAXB的优势</P>
<P>author.setText(Float.toString(50.0f));</P>
<P>Stringindent="";</P>
<P>booleannewLines=true;</P>
<P>XMLOutputteroutp=newXMLOutputter(indent,newLines,"GBK");</P>
<P>outp.output(doc,newFileOutputStream("exampleB.xml"));</P>
<P>}</P>
<P>};</P>
<P>执行结果exampleB.xml：</P>
<P>&lt;?xmlversion="1.0"encoding="GBK"?&gt;</P>
<P>&lt;bookList&gt;</P>
<P>&lt;bookhot=”true”&gt;</P>
<P>&lt;name&gt;Java编程入门&lt;/name&gt;</P>
<P>&lt;author&gt;50.0&lt;/author&gt;</P>
<P>&lt;publishDate&gt;2002-6-6&lt;/publishDate&gt;</P>
<P>&lt;price&gt;35.0&lt;/price&gt;</P>
<P>&lt;/book&gt;</P>
<P>&lt;book&gt;</P>
<P>&lt;name&gt;XML在Java中的应用&lt;/name&gt;</P>
<P>&lt;author&gt;李四&lt;/author&gt;</P>
<P>&lt;publishDate&gt;2002-9-16&lt;/publishDate&gt;</P>
<P>&lt;price&gt;92.0&lt;/price&gt;</P>
<P>&lt;/book&gt;</P>
<P>&lt;/bookList&gt;</P>
<P>&lt;?xml-stylesheethref="bookList.html.xsl"type="text/xsl"?&gt;</P>
<P>在默认情况下，JDOM的Element类的getText()这类的方法不会过滤空白字符，如果你需要过滤，用setTextTrim()</P></DIV></DIV></DIV></DIV></DIV></DIV></DIV></DIV><img src ="http://www.blogjava.net/fjq639/aggbug/24813.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fjq639/" target="_blank">黑石</a> 2005-12-20 16:20 <a href="http://www.blogjava.net/fjq639/archive/2005/12/20/24813.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>jdom学习:读取xml文件</title><link>http://www.blogjava.net/fjq639/archive/2005/12/20/24806.html</link><dc:creator>黑石</dc:creator><author>黑石</author><pubDate>Tue, 20 Dec 2005 08:01:00 GMT</pubDate><guid>http://www.blogjava.net/fjq639/archive/2005/12/20/24806.html</guid><wfw:comment>http://www.blogjava.net/fjq639/comments/24806.html</wfw:comment><comments>http://www.blogjava.net/fjq639/archive/2005/12/20/24806.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/fjq639/comments/commentRss/24806.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fjq639/services/trackbacks/24806.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;<FONT color=#333333>&nbsp;&nbsp;<BR><FONT color=#000000><STRONG>官方网站</STRONG>:</FONT><A HREF="/fjq639/admin/官方网站:http://www.jdom.org/downloads/index.html">http://www.jdom.org/downloads/index.html</A><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 用JDOM读取XML文件需先用org.jdom.input.SAXBuilder对象的build()方法创建Document对象,然后用Document类、Element类等的方法读取所需的内容。IBM&nbsp;:&nbsp;developerWorks&nbsp;中国站上有一个很好的例子： <BR>&lt;?xml&nbsp;version="1.0"&nbsp;encoding="UTF-8"?&gt; <BR>&lt;HD&gt; <BR>&nbsp;&nbsp;&lt;disk&nbsp;name="C"&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&lt;capacity&gt;8G&lt;/capacity&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&lt;directories&gt;200&lt;/directories&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&lt;files&gt;1580&lt;/files&gt; <BR>&nbsp;&nbsp;&lt;/disk&gt; <BR><BR>&nbsp;&nbsp;&lt;disk&nbsp;name="D"&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&lt;capacity&gt;10G&lt;/capacity&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&lt;directories&gt;500&lt;/directories&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&lt;files&gt;3000&lt;/files&gt; <BR>&nbsp;&nbsp;&lt;/disk&gt; <BR>&lt;/HD&gt; <BR><BR>上面的sample.xml文档，描述了某台电脑中硬盘的基本信息(根节点&lt;HD&gt;代表硬盘，&lt;disk&gt;标签代表硬盘分区，从它的name属性可以看出有两个盘符名称为"C"和"D"的分区；每个分区下都包含&lt;capacity&gt;,&lt;directories&gt;&lt;files&gt;三个节点，分别代表了分区的空间大小、目录数量、所含文件个数) <BR><BR>下面的程序读取此文件中的信息： <BR>import&nbsp;java.util.*; <BR>import&nbsp;org.jdom.*; <BR>import&nbsp;org.jdom.input.SAXBuilder; <BR>public&nbsp;class&nbsp;Sample1&nbsp;{ <BR>&nbsp;&nbsp;public&nbsp;static&nbsp;void&nbsp;main(String[]&nbsp;args)&nbsp;throws&nbsp;Exception{&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;SAXBuilder&nbsp;sb=new&nbsp;SAXBuilder(); <BR>&nbsp;&nbsp;&nbsp;&nbsp;Document&nbsp;doc=sb.build("sample.xml"); //构造文档对象<BR>&nbsp;&nbsp;&nbsp;&nbsp;Element&nbsp;root=doc.getRootElement(); //获取根元素<BR>&nbsp;&nbsp;&nbsp;&nbsp;List&nbsp;list=root.getChildren("disk");//取名字为disk的所有元素 <BR>&nbsp;&nbsp;&nbsp;&nbsp;for(int&nbsp;i=0;i&lt;list.size();i++){ <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Element&nbsp;element=(Element)list.get(i); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;name=element.getAttributeValue("name"); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;capacity=element.getChildText("capacity");//取disk子元素capacity的内容 <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;directories=element.getChildText("directories"); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;files=element.getChildText("files"); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("磁盘信息:"); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("分区盘符:"+name); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("分区容量:"+capacity); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("目录数:"+directories); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("文件数:"+files); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("-----------------------------------"); <BR>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; <BR>&nbsp;&nbsp;} <BR>} <BR>运行结果： <BR>C:\java&gt;java&nbsp;&nbsp;&nbsp;Sample1 <BR>磁盘信息: <BR>分区盘符:C <BR>分区容量:8G <BR>目录数:200 <BR>文件数:1580 <BR>----------------------------------- <BR>磁盘信息: <BR>分区盘符:D <BR>分区容量:10G <BR>目录数:500 <BR>文件数:3000 <BR>----------------------------------- </FONT><img src ="http://www.blogjava.net/fjq639/aggbug/24806.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fjq639/" target="_blank">黑石</a> 2005-12-20 16:01 <a href="http://www.blogjava.net/fjq639/archive/2005/12/20/24806.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate学习</title><link>http://www.blogjava.net/fjq639/archive/2005/12/19/24635.html</link><dc:creator>黑石</dc:creator><author>黑石</author><pubDate>Mon, 19 Dec 2005 06:48:00 GMT</pubDate><guid>http://www.blogjava.net/fjq639/archive/2005/12/19/24635.html</guid><wfw:comment>http://www.blogjava.net/fjq639/comments/24635.html</wfw:comment><comments>http://www.blogjava.net/fjq639/archive/2005/12/19/24635.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/fjq639/comments/commentRss/24635.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fjq639/services/trackbacks/24635.html</trackback:ping><description><![CDATA[<P>&nbsp;&nbsp;&nbsp; <FONT style="BACKGROUND-COLOR: #d3d3d3" size=1>参考书籍</FONT>:<FONT size=1><STRONG>深入浅除Hibernate<BR><BR></STRONG>&nbsp;<FONT color=#000000>&nbsp;&nbsp;<FONT style="BACKGROUND-COLOR: #ffffff">&nbsp; <FONT style="BACKGROUND-COLOR: #d3d3d3">作&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;者</FONT><STRONG>:夏昕 曹晓钢 唐勇</STRONG></FONT></FONT><FONT color=#d3d3d3><BR></FONT><BR><BR><BR>&nbsp;&nbsp;&nbsp; </FONT></P><img src ="http://www.blogjava.net/fjq639/aggbug/24635.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fjq639/" target="_blank">黑石</a> 2005-12-19 14:48 <a href="http://www.blogjava.net/fjq639/archive/2005/12/19/24635.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>