﻿<?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-温馨虫窝-文章分类-XML</title><link>http://www.blogjava.net/su/category/525.html</link><description>给自己一个温馨的家</description><language>zh-cn</language><lastBuildDate>Fri, 02 Mar 2007 03:32:18 GMT</lastBuildDate><pubDate>Fri, 02 Mar 2007 03:32:18 GMT</pubDate><ttl>60</ttl><item><title>(转自IBM)用 JDOM 简化 XML 编程</title><link>http://www.blogjava.net/su/articles/1591.html</link><dc:creator>温馨虫窝</dc:creator><author>温馨虫窝</author><pubDate>Tue, 01 Mar 2005 06:59:00 GMT</pubDate><guid>http://www.blogjava.net/su/articles/1591.html</guid><wfw:comment>http://www.blogjava.net/su/comments/1591.html</wfw:comment><comments>http://www.blogjava.net/su/articles/1591.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/su/comments/commentRss/1591.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/su/services/trackbacks/1591.html</trackback:ping><description><![CDATA[<P><FONT face="Arial, sans-serif" size=-1>作为开发人员，您可能听说过 80-20 规则，在其它领域被称为 Pareto 法则：一种过程或方法能适应所有可能情况的 80%，另外的 20% 则需要根据具体情况来处理。软件开发的必然结果是：对于开发人员而言，有了给定的技术后就能非常容易地完成可能要做的工作的 80%。</FONT></P>
<P><FONT face="Arial, sans-serif" size=-1>当然，软件产品和标准并不总是根据 80-20 规则发展的。特别的，Java XML 的缺陷就是这条规则的一个例外。Java 的编程世界拥有很多的 API -- 一些是自己开发的，一些是由几个大公司开发并被制定为标准的 -- 他们提供了解决特殊 XML 任务的成熟解决方案。作为 XML 普遍性的证明，每个新任务都存在着一种新技术，但如何将它们结合在一起，又如何寻找一种合适的工具去完成必须重复做的任务中的 80% -- 利用 Java 语言的直观映象的基本 XML 树操作？JDOM 正好是用来解决上述问题的一个 XML API。</FONT></P>
<P><FONT face="Arial, sans-serif" size=-1><A id=1 name=1></A><B class=atitle2>标记：Java 和 XML</B><BR>在许多方面，Java 语言已变成供 XML 选择的一种编程语言。由于 Apache 软件基金会和 IBM alphaWorks 所做的开创性工作，现在已有完整的工具链用于创建，操作，传送文档和对 XML 文档进行语法分析。</FONT></P>
<P><FONT face="Arial, sans-serif" size=-1>但是，虽然许多 Java 开发人员每天都在使用 XML，Sun 却在将 XML 整合进 Java 平台方面落后了。因为在 XML 成为从商家对商家集成到 Web 站点内容流水化等方面的关键技术之前，Java 2 平台就已经非常流行了。Sun 已经使用 JSR 过程使之成为现存 XML API 的鼻祖，这一点已被广泛接受。目前最显著的是加入了 JAXP （用于 XML 语法分析的 Java API），其中包含了三个软件包：</FONT></P>
<UL>
<LI><FONT face="Arial, sans-serif" size=-1><CODE>org.w3c.dom</CODE>，W3C 推荐的用于 XML 标准规划文档对象模型的 Java 工具</FONT> 
<LI><FONT face="Arial, sans-serif" size=-1><CODE>org.xml.sax</CODE>，用于对 XML 进行语法分析的事件驱动的简单 API</FONT> 
<LI><FONT face="Arial, sans-serif" size=-1><CODE>javax.xml.parsers</CODE>，工厂化工具，允许应用程序开发人员获得并配置特殊的语法分析器工具</FONT> </LI></UL>
<P><FONT face="Arial, sans-serif" size=-1>尽管对于 Java 开发人员而言，有了这些软件包是件好事，但它仅仅代表获得了现有 API 标准的正式许可而已，并没有在提供一流的 Java-XML 互操作性方面取得了巨大飞跃。核心 Java 平台所缺乏的是将 XML 文档作为 Java 对象操作的直观接口。</FONT></P>
<P><FONT face="Arial, sans-serif" size=-1>进入 JDOM。JDOM 是两位著名的 Java 开发人员兼作者，Brett Mclaughlin 和 Jason Hunter 的创作成果， <!-- (see <a href="#resources">Resources</a> for links to some of their work) -->2000 年初在类似于 Apache 协议的许可下，JDOM 作为一个开放源代码项目正式开始研发，JDOM 作为一个开放源代码项目正式开始了。它已成长为包含来自广泛的 Java 开发人员的投稿、集中反馈及错误修复的系统，并致力于建立一个完整的基于 Java 平台的解决方案，通过 Java 代码来访问、操作并输出 XML 数据。</FONT></P>
<P><FONT face="Arial, sans-serif" size=-1><A id=2 name=2></A><B class=atitle2>这是 JDOM 适合的 API、哑元</B><BR>JDOM 能够替换 <CODE>org.w3c.dom</CODE> 软件包来有计划地操作 XML 文档。它并不是一个简单的替代品，实际上 JDOM 和 DOM 能够愉快地并存。另外，尽管它提供的类的封装从配置和运行分析器执行中分担了大量工作，但它不负责根据文本输入来对 XML 进行语法分析。JDOM 建立在现有的 API 的能力之上，正如项目网页所表述的“一个更好的捕鼠器”。</FONT></P>
<P><FONT face="Arial, sans-serif" size=-1>要理解需要备用 API 的原因，就要考虑 W3C DOM 设计的局限性：</FONT></P>
<UL>
<LI><FONT face="Arial, sans-serif" size=-1><B>语言独立。</B>DOM 并不是用人们心目中的 Java 语言设计的。虽然这种方法保留了在不同语言中非常相似的 API，它也使那些习惯 Java 语言的程序员感到更麻烦。例如：Java 语言内建了一种 <CODE>String</CODE> 类，而 DOM 则规范定义了自己的 <CODE>Text</CODE> 类。<BR><BR></FONT>
<LI><FONT face="Arial, sans-serif" size=-1><B>严格的层次结构。</B>DOM API 直接沿袭了 XML 规范。在 XML 中，每件东西都是一个结点，因此您能在 DOM 中找到一个几乎每件东西都可以扩展的基于 <CODE>Node</CODE> 的接口和返回 <CODE>Node</CODE> 的一系列方法。就多态性的观点来讲，它是优秀的，但鉴于如上解释，它在 Java 语言中的应用是困难而且不便的，其中从 <CODE>Node</CODE> 向叶类型作显式下拉会导致代码的冗长和难以理解。<BR><BR></FONT>
<LI><FONT face="Arial, sans-serif" size=-1><B>接口驱动。</B>公共 DOM API 仅由接口组成（<CODE>Exception</CODE> 类是一个例外，但恰恰足够了）。w3c 对提供实现并不感兴趣，它只对定义接口（比较有意义）感兴趣。但它也意味着作为 Java 程序员使用 API 在创建 XML 对象时增加了分散程度，因为 w3c 标准大量使用工厂化的类和类似的灵活的但不直接的模式。在某些应用中，XML 文档是仅由语法分析器建立的，而从不会由应用程序级代码建立，这是不相关的。但是，随着 XML 更广泛的使用，并不是所有问题都继续需要由语法分析器来驱动。应用程序的开发人员需要一个更方便的方法有计划地构造 XML 对象。</FONT> </LI></UL>
<P><FONT face="Arial, sans-serif" size=-1>对于程序员，这些约束意味着庞大（在内存占用和接口大小方面）的和难掌握的 API，学习和使用都很难。相反，JDOM 是作为一种轻量级 API 被制定的，最主要的是它是以 Java 为中心的。它在遵循 DOM 主要规则的基础上除去了上述缺点：</FONT></P>
<UL>
<LI><FONT face="Arial, sans-serif" size=-1><B>JDOM 是 Java 平台专用的。</B>只要有可能，API 都使用 Java 语言的内建 <CODE>String</CODE> 支持，因此文本值也适用于 <CODE>String</CODE>。它还可利用 Java 2 平台的类集，如 <CODE>List</CODE> 和 <CODE>Iterator</CODE>，给程序员提供了一个丰富的并且和 Java 语言类似的环境。<BR><BR></FONT>
<LI><FONT face="Arial, sans-serif" size=-1><B>没有层次性。</B>在 JDOM 中，XML 元素就是 <CODE>Element</CODE> 的实例，XML 属性就是 <CODE>Attribute</CODE> 的实例，XML 文档本身就是 <CODE>Document</CODE> 的实例。由于在 XML 中所有这些都代表了不同的概念，因此它们总是作为自己的类型被引用，而不是作为一个含糊的“结点”。<BR><BR></FONT>
<LI><FONT face="Arial, sans-serif" size=-1><B>类驱动。</B>因为 JDOM 对象就是像 <CODE>Document</CODE>、<CODE>Element</CODE> 和 <CODE>Attribute</CODE> 这些类的直接实例，因此创建一个新 JDOM 对象就如在 Java 语言中使用 <CODE>new</CODE> 操作符一样容易。它还意味着不需要进行工厂化接口配置 -- JDOM 的使用是直截了当的。</FONT> </LI></UL>
<P><FONT face="Arial, sans-serif" size=-1><A id=3 name=3></A><B class=atitle2>看，没有 <CODE>Node</CODE>：建立和操作 JDOM 文档</B><BR>JDOM 使用标准的 Java 编码模式。只要有可能，它使用 Java <CODE>new</CODE> 操作符而不用复杂的工厂化模式，使对象操作即便对于初学用户也很方便。例如，让我们看一下如何随便使用 JDOM 建立一个简单的 XML 文档。我们将要建立的结构如清单 1 所示。（从<A href="http://www-900.ibm.com/developerWorks/cn/java/j-jdom/index.shtml#resources">参考资料</A>上可下载关于本文的完整代码）</FONT></P>
<P><FONT face="Arial, sans-serif" size=-1><A id=code1 name=code1></A><B>清单 1. 建立 XML 文档样本</B></FONT></P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD><PRE><CODE>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;car vin="123fhg5869705iop90"&gt;
  &lt;!--Description of a car--&gt;
  &lt;make&gt;Toyota&lt;/make&gt;
  &lt;model&gt;Celica&lt;/model&gt;
  &lt;year&gt;1997&lt;/year&gt;
  &lt;color&gt;green&lt;/color&gt;
  &lt;license state="CA"&gt;1ABC234&lt;/license&gt;
&lt;/car&gt;
</CODE>
</PRE></TD></TR></TBODY></TABLE><BR><BR><FONT face="Arial, sans-serif" size=-1></FONT>
<P><FONT face="Arial, sans-serif" size=-1>注意：我们将建立<A href="http://www-900.ibm.com/developerWorks/cn/java/j-jdom/j-jdom_completecode.html" target=_blank>示例文档</A>，在下面的清单 2 到清单 7 中有详细描述。</FONT></P>
<P><FONT face="Arial, sans-serif" size=-1>开始，让我们先创建一个根元素，并将其添加到文档中：</FONT></P>
<P><FONT face="Arial, sans-serif" size=-1><A id=code2 name=code2></A><B>清单 2. 创建一个 <CODE>Document</CODE></B></FONT></P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD><PRE><CODE>Element carElement = new Element("car");
Document myDocument = new Document(carElement);
</CODE>
</PRE></TD></TR></TBODY></TABLE><BR><BR><FONT face="Arial, sans-serif" size=-1></FONT>
<P><FONT face="Arial, sans-serif" size=-1>这一步创建一个新 <CODE>org.jdom.Element</CODE>，并将其作为 <CODE>org.jdom.Document</CODE> <CODE>myDocument</CODE> 的根元素。（如果您使用<A href="http://www-900.ibm.com/developerWorks/cn/java/j-jdom/index.shtml#resources">参考资料</A>中提供的样本代码，请务必导入 <CODE>org.jdom.*</CODE>。）因为一个 XML 文档必须一直有一个唯一的根元素，所以 <CODE>Document</CODE> 将 <CODE>Element</CODE> 放在它的构造器中。</FONT></P>
<P><FONT face="Arial, sans-serif" size=-1>下一步，添加 <CODE>vin</CODE> 属性：</FONT></P>
<P><FONT face="Arial, sans-serif" size=-1><A id=code3 name=code3></A><B>清单 3. 添加一个 <CODE>Attribute</CODE></B></FONT></P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD><PRE><CODE>carElement.addAttribute(new Attribute("vin", "123fhg5869705iop90"));
</CODE>
</PRE></TD></TR></TBODY></TABLE><BR><BR><FONT face="Arial, sans-serif" size=-1></FONT>
<P><FONT face="Arial, sans-serif" size=-1>添加元素也是很简单的。这里我们添加 <CODE>make</CODE> 元素：</FONT></P>
<P><FONT face="Arial, sans-serif" size=-1><A id=code4 name=code4></A><B>清单 4. 元素和子元素</B></FONT></P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD><PRE><CODE>Element make = new Element("make");
make.addContent("Toyota");
carElement.addContent(make);
</CODE>
</PRE></TD></TR></TBODY></TABLE><BR><BR><FONT face="Arial, sans-serif" size=-1></FONT>
<P><FONT face="Arial, sans-serif" size=-1>由于 <CODE>Element</CODE> 的 <CODE>addContent</CODE> 方法返回 <CODE>Element</CODE>，我们也可以这样写：</FONT></P>
<P><FONT face="Arial, sans-serif" size=-1><A id=code5 name=code5></A><B>清单 5. 用简洁形式添加元素</B></FONT></P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD><PRE><CODE>carElement.addContent(new Element("make").addContent("Toyota"));
</CODE>
</PRE></TD></TR></TBODY></TABLE><BR><BR><FONT face="Arial, sans-serif" size=-1></FONT>
<P><FONT face="Arial, sans-serif" size=-1>这两个语句完成了相同的工作。有些人认为第一个示例可读性更好，但是如果您一次建立许多元素，您会觉得第二个示例可读性更好。要完成构建文档：</FONT></P>
<P><FONT face="Arial, sans-serif" size=-1><A id=code6 name=code6></A><B>清单 6. 添加其余的元素</B></FONT></P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD><PRE><CODE>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"));
</CODE>
</PRE></TD></TR></TBODY></TABLE><BR><BR><FONT face="Arial, sans-serif" size=-1></FONT>
<P><FONT face="Arial, sans-serif" size=-1>您会注意到对于 <CODE>license</CODE> 元素，我们不但添加了元素的内容，还为其添加了一个属性，表明许可已被发出了这个状态。这是因为 <CODE>Element</CODE> 的 <CODE>addContent</CODE> 方法总是返回 <CODE>Element</CODE> 本身，而不是一个无效的声明。</FONT></P>
<P><FONT face="Arial, sans-serif" size=-1>用同样的方法添加注释部分或其它标准 XML 类型：</FONT></P>
<P><FONT face="Arial, sans-serif" size=-1><A id=code7 name=code7></A><B>清单 7. 添加一条注释</B></FONT></P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD><PRE><CODE>carElement.addContent(new Comment("Description of a car"));
</CODE>
</PRE></TD></TR></TBODY></TABLE><BR><BR><FONT face="Arial, sans-serif" size=-1></FONT>
<P><FONT face="Arial, sans-serif" size=-1>操作文档也是用类似方式。例如，要引用 <CODE>year</CODE> 元素，我们使用 <CODE>Element</CODE> 的 <CODE>getChild</CODE> 方法：</FONT></P>
<P><FONT face="Arial, sans-serif" size=-1><A id=code8 name=code8></A><B>清单 8. 访问子元素</B></FONT></P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD><PRE><CODE>Element yearElement = carElement.getChild("year");
</CODE>
</PRE></TD></TR></TBODY></TABLE><BR><BR><FONT face="Arial, sans-serif" size=-1></FONT>
<P><FONT face="Arial, sans-serif" size=-1>该语句实际上将返回第一个元素名为 <CODE>year</CODE> 的子 <CODE>Element</CODE>。 如果没有 <CODE>year</CODE> 元素，则调用返回一个空值。注意，我们不必回溯来自任何类似于 DOM <CODE>Node</CODE> 接口的返回值 -- <CODE>Element</CODE> 的子元素就是 <CODE>Element</CODE>。用类似的方式，我们可把 <CODE>year</CODE> 元素从文档中除去：</FONT></P>
<P><FONT face="Arial, sans-serif" size=-1><A id=code9 name=code9></A><B>清单 9. 除去子元素</B></FONT></P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD><PRE><CODE>boolean removed = carElement.removeChild("year");
</CODE>
</PRE></TD></TR></TBODY></TABLE><BR><BR><FONT face="Arial, sans-serif" size=-1></FONT>
<P><FONT face="Arial, sans-serif" size=-1>这次调用将只除去 <CODE>year</CODE> 元素；文档的其余部分保持不变。</FONT></P>
<P><FONT face="Arial, sans-serif" size=-1>到目前为止，我们已经涵盖了文档的生成和操作。要将完成的文档输出至控制台，可使用 JDOM 的 <CODE>XMLOutputter</CODE> 类：</FONT></P>
<P><FONT face="Arial, sans-serif" size=-1><A id=code10 name=code10></A><B>清单 10. 将 JDOM 转化为 XML 文本</B></FONT></P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD><PRE><CODE>try {
    XMLOutputter outputter = new XMLOutputter("  ", true);
    outputter.output(myDocument, System.out);
} catch (java.io.IOException e) {
    e.printStackTrace();
}
</CODE>
</PRE></TD></TR></TBODY></TABLE><BR><BR><FONT face="Arial, sans-serif" size=-1></FONT>
<P><FONT face="Arial, sans-serif" size=-1><CODE>XMLOutputter</CODE> 有几个格式选项。这里我们已指定希望子元素从父元素缩进两个空格，并且希望元素间有空行。<CODE> XMLOutputter</CODE> 可输出到 <CODE>Writer</CODE> 或 <CODE>OutputStream</CODE>。为输出到文件，我们可以简单地将输出行简化为：</FONT></P>
<P><FONT face="Arial, sans-serif" size=-1><A id=code11 name=code11></A><B>清单 11. 使用 <CODE>FileWriter</CODE> 输出 XML</B></FONT></P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD><PRE><CODE>FileWriter writer = new FileWriter("/some/directory/myFile.xml");
outputter.output(myDocument, writer);
writer.close();
</CODE>
</PRE></TD></TR></TBODY></TABLE><BR><BR><FONT face="Arial, sans-serif" size=-1></FONT>
<P><FONT face="Arial, sans-serif" size=-1><A id=4 name=4></A><B class=atitle2>与其它方法良好协作：和现有的 XML 工具进行互操作</B><BR>JDOM 的一个有趣特征是和其它 API 有互操作性。使用 JDOM，不仅能把文档输出到 <CODE>Stream</CODE> 或 <CODE>Reader</CODE>，还可将文档作为 SAX <CODE>Event Stream</CODE> 或作为 DOM <CODE>Document</CODE>。这种灵活性允许 JDOM 能在多种环境下使用或被添加到已经在使用另一种方法处理 XML 的系统中去。正如我们在后面一个示例中所看到的，它还允许 JDOM 使用其它的还不能识别 JDOM 的数据结构的 XML 工具。</FONT></P>
<P><FONT face="Arial, sans-serif" size=-1>JDOM 的另一个用处是它能够读取并操作现有的 XML 数据。使用 <CODE>org.jdom.input</CODE> 中的一个类可以阅读结构很规范的 XML 文件。在这个示例中我们使用 <CODE>SAXBuilder</CODE>：</FONT></P>
<P><FONT face="Arial, sans-serif" size=-1><A id=code12 name=code12></A><B>清单 12. 使用 <CODE>SAXBuilder</CODE> 对 XML 文件进行语法分析</B></FONT></P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD><PRE><CODE>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();
}
</CODE>
</PRE></TD></TR></TBODY></TABLE><BR><BR><FONT face="Arial, sans-serif" size=-1></FONT>
<P><FONT face="Arial, sans-serif" size=-1>您可以用清单 2 到清单 7 中显示的方法来操作通过这个过程建立的文档。</FONT></P>
<P><FONT face="Arial, sans-serif" size=-1>JDOM 的另一个实用应用程序将其与 Apache 的 Xalan 产品结合在一起（请参阅<A href="http://www-900.ibm.com/developerWorks/cn/java/j-jdom/index.shtml#resources">参考资料</A>）。使用上面的汽车示例，我们将为在线汽车经销商建立一个 Web 页面，显示特定汽车的详细信息。首先，假设我们上面建立的文档显示我们准备呈现给用户的汽车的信息。下一步，我们将把这个 JDOM <CODE>Document</CODE> 与一个 XSL 样式表结合起来并把 HTML 格式的结果输出到 servlet 的 <CODE>OutputStream</CODE> 上以便在用户的浏览器中显示。</FONT></P>
<P><FONT face="Arial, sans-serif" size=-1>在本例中，我们准备使用的 XSL 样式表被称为 <CODE>car.xsl</CODE>：</FONT></P>
<P><FONT face="Arial, sans-serif" size=-1><A id=code13 name=code13></A><B>清单 13. 用于将汽车记录转换为 HTML 的 XSL 文档</B></FONT></P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD><PRE><CODE>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
<!--&lt;xsl:stylesheet xmlns:xsl="http://....."> -->
&lt;xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
  &lt;xsl:template match="/car"&gt;
    &lt;html&gt;
        &lt;head&gt;
          &lt;title&gt;&lt;xsl:value-of select="make"/&gt; &lt;xsl:value-of select="model"/&gt;
        &lt;/head&gt;
        &lt;body&gt;
          &lt;h1&gt;&lt;xsl:value-of select="make"/&gt;&lt;/h1&gt;&lt;br /&gt;
          &lt;h2&gt;&lt;xsl:value-of select="model"/&gt;&lt;/h2&gt;&lt;br /&gt;
          &lt;table border="0"&gt;
          &lt;tr&gt;&lt;td&gt;VIN:&lt;/td&gt;&lt;td&gt;&lt;xsl:value-of select="@vin"/&gt;&lt;/td&gt;&lt;/tr&gt;
          &lt;tr&gt;&lt;td&gt;Year:&lt;/td&gt;&lt;td&gt;&lt;xsl:value-of select="year"/&gt;&lt;/td&gt;&lt;/tr&gt;
          &lt;tr&gt;&lt;td&gt;Color:&lt;/td&gt;&lt;td&gt;&lt;xsl:value-of select="color"/&gt;&lt;/td&gt;&lt;/tr&gt;
          &lt;/table&gt;
        &lt;/body&gt;
    &lt;/html&gt;
  &lt;/xsl:template&gt;
&lt;/xsl:stylesheet&gt;
</CODE>
</PRE></TD></TR></TBODY></TABLE><BR><BR><FONT face="Arial, sans-serif" size=-1></FONT>
<P><FONT face="Arial, sans-serif" size=-1>现在我们将把 <CODE>org.jdom.Document</CODE> 转换为 DOM <CODE>Document</CODE>，并将其与显示我们的 XSL 和 <CODE>OutputStream</CODE> 的文件一起提供给 Xalan，<CODE>OutputStream</CODE> 是我们从我们假定的使用 servlet（如清单 14 所示）的应用服务器上获取的。</FONT></P><FONT face="Arial, sans-serif" size=-1><A id=code14 name=code14></A><B>清单 14. 使用 JDOM 和 Xalan 创建 HTML 文档</B></FONT> 
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD><PRE><CODE>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);
</CODE>
</PRE></TD></TR></TBODY></TABLE>
<P><FONT face="Arial, sans-serif" size=-1>在这个示例中，输出是通过 Java servlet 的 <CODE>HTTPResponse</CODE> <CODE>OutputStream</CODE> 流出。然而，输出流可以象早期的使用 <CODE>XMLOutputter</CODE> 的实例一样简单的通过文件流输出。我们使用 <CODE>DOMOutputter</CODE> 为 Xalan 生成 XML 源代码。但是我们可以生成相同的输出，方法是使用 <CODE>XMLOutputter</CODE> 将我们的 XML 文档作为 <CODE>String</CODE> 输出并使其进入 <CODE>StreamSource</CODE>。说到灵活性：JDOM 可将它的结构作为 <CODE>String</CODE>、SAX <CODE>Event Stream</CODE> 或 DOM <CODE>Document</CODE> 输出。这允许 JDOM 与能把任何这些模型作为输入的工具一起工作。（关于附加功能，请访问 JDOM Web 站点的 <CODE>contrib</CODE> 包，在那里您将发现一个基于 JDOM 工具的宝库，可提供基于 JDBC ResultSet 的构建器、XPATH 实现方法和其它更多工具。）</FONT></P>
<P><FONT face="Arial, sans-serif" size=-1>在短短几行代码中，JDOM 启用了许多功能，我们已经在 XML 中分析过并有计划地创建了 XML 文档，操作了那些文档，并使用它们产生 XML 驱动的 Web 页面。</FONT></P><!-- SIDEBAR -->
<TABLE cellSpacing=0 cellPadding=5 width="35%" align=right border=1>
<TBODY>
<TR>
<TD background=/developerWorks/cn/i/bg-gold.gif><FONT face="arial, sans-serif" size=-1><A id=sidebar name=sidebar><B>Sun 和 JDOM：名字里包含了些什么？</B></A><BR>JDOM 的 1.0 正式发行版可能与其在 Java Community Process 中的一贯发展方向相符。作为 JSR-102 提交的 JDOM 已经批准成为了核心 Java 平台的最终包含部分。Sun 对此的评价是：“JDOM 确实明显地比早期的 API 更易于使用，因此我们相信它将成为 Java 平台有用的附加物。”据 JSR 透露，JDOM 1.0 发行版的包装可能由 "org.jdom" 变为 "javax.xml"。尽管前景乐观，但开发人员可能最终不得不改变他们的代码来使用新代码。</FONT></TD></TR></TBODY></TABLE><!-- END OF SIDEBAR -->
<P><FONT face="Arial, sans-serif" size=-1><A id=5 name=5></A><B class=atitle2>JDOM 的成长：前景一瞥</B><BR>正如此文所提的那样，JDOM 项目已经发布了它的 Beta 6 版本。甚至在 beta 状态下，对于许多真实世界中的实现方法来说，JDOM 已经被证明是稳定的一种了。尽管大部分的 API 已经稳固了，但在一些领域中仍在进行一些会对现有的接口造成潜在影响的工作。因此，在这点上，任何在进行的开发项目都不需要因为害怕一个错误多多的实现方法而回避 JDOM，但是要考虑这样一个事实：某些方法结构或某些语义仍有可能在最终发布和被核心 Java API 所采用之前发生改变。（请参阅<A href="http://www-900.ibm.com/developerWorks/cn/java/j-jdom/sidebar">名字里包含了些什么？</A>）</FONT></P>
<P><FONT face="Arial, sans-serif" size=-1>JDOM 紧接着要做的是致力于稳定 API 并对实现方法的各方面性能问题作出评估。其它方面有所进展，但也造成了对一些应用程序开发人员的阻碍，包括支持 DTD 实体和其它不太常见的构造。沿着这条路再进一步就是对 XPATH（它是一种象 XSLT 这样的应用程序所特有的 XML 路径语言）的核心支持以及更多地集成 XML 数据源。</FONT></P>
<P><FONT face="Arial, sans-serif" size=-1>那么，概况地说，JDOM 是否比现有的 XML API 好呢？如果您梦想 Java，那答案可能是“是的”。JDOM 并非意味着将取代您所喜爱的语法分析或 XML 敏感型数据库，但其设计原则有助于为试图掌握 XML 世界的新老 Java 开发人员提供快速的学习途径。</FONT></P><img src ="http://www.blogjava.net/su/aggbug/1591.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/su/" target="_blank">温馨虫窝</a> 2005-03-01 14:59 <a href="http://www.blogjava.net/su/articles/1591.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>（转）从 DOM 转换</title><link>http://www.blogjava.net/su/articles/1589.html</link><dc:creator>温馨虫窝</dc:creator><author>温馨虫窝</author><pubDate>Tue, 01 Mar 2005 06:45:00 GMT</pubDate><guid>http://www.blogjava.net/su/articles/1589.html</guid><wfw:comment>http://www.blogjava.net/su/comments/1589.html</wfw:comment><comments>http://www.blogjava.net/su/articles/1589.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/su/comments/commentRss/1589.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/su/services/trackbacks/1589.html</trackback:ping><description><![CDATA[在本文中，您会了解如何将 DOM 结构转换成 SAX 和 JDOM，从而可以与不使用 DOM 的应用程序通信。本文列出的代码演示了如何从 DOM 转换到供 SAX 使用的输出流，以及如何从 DOM 到 JDOM 的转换。<BR><BR>如果您对 W3C 的 DOM（文档对象模型）感兴趣而且认为 SAX 很灵巧的话，那么您必须找出一种方法将 DOM 转换成应用程序开发人员使用的其它格式。当然，这些其它格式是指 SAX 和 JDOM。如果必须将 DOM 作为输入且要将它转换成其它格式时，要做什么？这当然是一个值得研究的问题。由于 DOM 提供了完整的文档表示，将它转换成另外一种格式当然是可行的。在本文中，您将了解如何执行从 DOM 到 SAX 或 JDOM 的转换。<BR><BR>从 DOM 到 SAX<BR>遗憾的是，DOM 级别 1 和更新的级别 2 没有提供将 DOM 树输出成 SAX 或其它格式的方式。结果是每个语法分析器实现都提供了一组用于输出的定制 API，实现的独立性丧失了。换句话说，您的代码只能与那个为它编写的语法分析器一起工作（如 Crimson、Xerces 或 Oracle 等等）。DOM 级别 3 被认为是提供了这项功能，所以我们都必须静观 DOM 级别 3 能提供什么输出方法。同时，查看一下供应商提供的有关编写或串行化 DOM 树的文档。例如使用 Apache Xerces，需要使用如清单 1 中所示的 org.apache.xml.serialize.XMLSerializer 类。 在每一种情形，您将有可能必须以流的形式输出 DOM 树，然后将这个流交给 SAX 进行后续处理。请注意，清单 1 中仅显示了以流的形式输出 DOM 树；然后可以使用这个流作为 SAX 处理器的输入。<BR><BR>清单 1. 将 DOM 转换成输出流（供 SAX 使用） <BR>import org.apache.xerces.parsers.DOMParser;<BR>import org.apache.xml.serialize.XMLSerializer;<BR>import org.xml.sax.InputSource;<BR>import org.w3c.dom.Document;<BR><BR>public class PrintDOMTree {<BR><BR>public static void main(String[] args) {<BR>try {<BR>InputSource source = new InputSource(args[0]);<BR>DOMParser parser = new DOMParser();<BR>parser.parse(source);<BR>Document doc = parser.getDocument();<BR><BR>XMLSerializer serializer = new XMLSerializer();<BR>// Insert your PipedOutputStream here instead of System.out!<BR>serializer.setOutputByteStream(System.out);<BR>serializer.serialize(doc);<BR>} catch (Exception e) {<BR>e.printStackTrace();<BR>}<BR>}<BR><BR>} <BR><BR><BR><BR><BR>从 DOM 到 JDOM<BR>将 DOM 转换成 JDOM 要比将 DOM 转换成 SAX 简单。这事实上很有意义，因为您一旦有了 DOM 树，就有可能有机会从 SAX 处理数据。事实上，很少有 SAX 最优处理 DOM 树的情况，因为您通过 DOM 表示来将 XML 存储在内存里时，已经用尽了内存。更为常见的工作是把作为 DOM 树的 XML 文档转换成 JDOM 树。由于这些格式都是文档表示，但在行为和功能性方面有潜在的不同，所以您可能想让其他人用您的 DOM 树并将它当作 JDOM 进行处理。您可能认为这是他们的工作，但您需要知道（至少！）如何从您的结构转换成他们的结构。<BR><BR>对于将 DOM 转换成 JDOM，JDOM API 向用户提供了 DOM Node，称为 org.jdom.input.DOMBuilder。这个类接受 DOM Document（以及其它一些 DOM 结构，如 Element 和 Attr），并将 DOM 树转换成 JDOM Document。这个操作并不复杂，所以我在清单 2 中简单地显示了该代码，让您了解一下实际过程。<BR><BR>清单 2. 将 DOM 转换成 JDOM <BR>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;Java&nbsp;imports</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000">import&nbsp;java.io.IOException;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;JDOM&nbsp;imports</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000">import&nbsp;org.jdom.JDOMException;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>import&nbsp;org.jdom.input.DOMBuilder;&nbsp;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>import&nbsp;org.jdom.output.XMLOutputter;&nbsp;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;SAX&nbsp;and&nbsp;DOM</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000">import&nbsp;org.xml.sax.InputSource;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;Xerces</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000">import&nbsp;org.apache.xerces.parsers.DOMParser;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top><BR><IMG id=Codehighlighter1_292_1056_Open_Image onclick="this.style.display='none'; Codehighlighter1_292_1056_Open_Text.style.display='none'; Codehighlighter1_292_1056_Closed_Image.style.display='inline'; Codehighlighter1_292_1056_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_292_1056_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_292_1056_Closed_Text.style.display='none'; Codehighlighter1_292_1056_Open_Image.style.display='inline'; Codehighlighter1_292_1056_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;DOMtoJDOM&nbsp;</SPAN><SPAN id=Codehighlighter1_292_1056_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_292_1056_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top></SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;DOM&nbsp;tree&nbsp;of&nbsp;input&nbsp;document</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top></SPAN><SPAN style="COLOR: #000000">org.w3c.dom.Document&nbsp;domDoc;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG id=Codehighlighter1_406_516_Open_Image onclick="this.style.display='none'; Codehighlighter1_406_516_Open_Text.style.display='none'; Codehighlighter1_406_516_Closed_Image.style.display='inline'; Codehighlighter1_406_516_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_406_516_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_406_516_Closed_Text.style.display='none'; Codehighlighter1_406_516_Open_Image.style.display='inline'; Codehighlighter1_406_516_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;DOMtoJDOM(String&nbsp;systemID)&nbsp;throws&nbsp;Exception&nbsp;</SPAN><SPAN id=Codehighlighter1_406_516_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_406_516_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>DOMParser&nbsp;parser&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;DOMParser();<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>parser.parse(</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;InputSource(systemID));<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>domDoc&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;parser.getDocument();<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;org.jdom.Document&nbsp;convert()&nbsp;<BR><IMG id=Codehighlighter1_589_745_Open_Image onclick="this.style.display='none'; Codehighlighter1_589_745_Open_Text.style.display='none'; Codehighlighter1_589_745_Closed_Image.style.display='inline'; Codehighlighter1_589_745_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_589_745_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_589_745_Closed_Text.style.display='none'; Codehighlighter1_589_745_Open_Image.style.display='inline'; Codehighlighter1_589_745_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>throws&nbsp;JDOMException,&nbsp;IOException&nbsp;</SPAN><SPAN id=Codehighlighter1_589_745_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_589_745_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top></SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;Create&nbsp;new&nbsp;DOMBuilder,&nbsp;using&nbsp;default&nbsp;parser</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top></SPAN><SPAN style="COLOR: #000000">DOMBuilder&nbsp;builder&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;DOMBuilder();<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>org.jdom.Document&nbsp;jdomDoc&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;builder.build(domDoc);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;jdomDoc;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG id=Codehighlighter1_787_1053_Open_Image onclick="this.style.display='none'; Codehighlighter1_787_1053_Open_Text.style.display='none'; Codehighlighter1_787_1053_Closed_Image.style.display='inline'; Codehighlighter1_787_1053_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_787_1053_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_787_1053_Closed_Text.style.display='none'; Codehighlighter1_787_1053_Open_Image.style.display='inline'; Codehighlighter1_787_1053_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">static</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;main(String[]&nbsp;args)&nbsp;</SPAN><SPAN id=Codehighlighter1_787_1053_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_787_1053_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG id=Codehighlighter1_793_1006_Open_Image onclick="this.style.display='none'; Codehighlighter1_793_1006_Open_Text.style.display='none'; Codehighlighter1_793_1006_Closed_Image.style.display='inline'; Codehighlighter1_793_1006_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_793_1006_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_793_1006_Closed_Text.style.display='none'; Codehighlighter1_793_1006_Open_Image.style.display='inline'; Codehighlighter1_793_1006_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">try</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN id=Codehighlighter1_793_1006_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_793_1006_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>DOMtoJDOM&nbsp;tester&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;DOMtoJDOM(args[</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">]);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>org.jdom.Document&nbsp;jdomDoc&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;tester.convert();<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top></SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;Output&nbsp;the&nbsp;document&nbsp;to&nbsp;System.out</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top></SPAN><SPAN style="COLOR: #000000">XMLOutputter&nbsp;outputter&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;XMLOutputter();<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>outputter.output(jdomDoc,&nbsp;System.</SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000">);<BR><IMG id=Codehighlighter1_1028_1051_Open_Image onclick="this.style.display='none'; Codehighlighter1_1028_1051_Open_Text.style.display='none'; Codehighlighter1_1028_1051_Closed_Image.style.display='inline'; Codehighlighter1_1028_1051_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_1028_1051_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1028_1051_Closed_Text.style.display='none'; Codehighlighter1_1028_1051_Open_Image.style.display='inline'; Codehighlighter1_1028_1051_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>}</SPAN></SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">catch</SPAN><SPAN style="COLOR: #000000">&nbsp;(Exception&nbsp;e)&nbsp;</SPAN><SPAN id=Codehighlighter1_1028_1051_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_1028_1051_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>e.printStackTrace();<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</SPAN></SPAN><SPAN style="COLOR: #000000">&nbsp;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top></SPAN></DIV></DIV><BR><BR><BR><BR>没有别的要说了。一旦您知道如何从 DOM 移向 SAX 和 JDOM 之后，就可以解决任何您需要的输出格式并且能够处理您将遇到的许多类型的 XML 表示。静待 DOM 级别 3 规范，以了解对于以标准的且与供应商无关的方式输出 DOM 树的更改，到那时，您就可以尽情使用 DOM 了！<BR><img src ="http://www.blogjava.net/su/aggbug/1589.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/su/" target="_blank">温馨虫窝</a> 2005-03-01 14:45 <a href="http://www.blogjava.net/su/articles/1589.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>（转）Java语言编程中更新XML文档的常用方法</title><link>http://www.blogjava.net/su/articles/1587.html</link><dc:creator>温馨虫窝</dc:creator><author>温馨虫窝</author><pubDate>Tue, 01 Mar 2005 06:36:00 GMT</pubDate><guid>http://www.blogjava.net/su/articles/1587.html</guid><wfw:comment>http://www.blogjava.net/su/comments/1587.html</wfw:comment><comments>http://www.blogjava.net/su/articles/1587.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/su/comments/commentRss/1587.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/su/services/trackbacks/1587.html</trackback:ping><description><![CDATA[本文简要的讨论了Java语言编程中更新XML文档的四种常用方法,并且分析这四种方法的优劣。其次,本文还对如何控制Java程序输出的XML文档的格式做了展开论述。<BR>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中删除)。<BR><BR>目前JAXP已经应用的十分普遍了,可以说是Java语言中处理XML文档的标准API。有些初学者在学习使用JAXP的过程中,经常会提出这样的问题:我编写的程序对DOM Tree做了更新,但是当程序退出以后,原始的XML文档并没有改变,还是老样子,如何实现对原始XML文档和DOM Tree的同步更新呢?咋一看来,在JAXP中似乎没有提供相应的接口/方法/类,这是很多初学者都感到困惑的问题。本文的主旨就在于解决这个问题,简单的介绍几种常用的同步更新原始XML文档和DOM Tree的方法。为了缩小讨论的范围,本文所涉及的XML解析器仅包括Apache Crimson和Apache Xerces,而XSLT处理器仅仅使用Apache Xalan。<BR><BR>方法一:直接读写XML文档<BR><BR>这也许是最笨最原始的办法了。当程序获取DOM Tree之后,应用DOM模型的Node接口的各个方法对DOM Tree进行更新,下一步应该对原始的XML文档进行更新了。我们可以运用递归的办法或者是应用TreeWalker类,遍历整个DOM Tree,与此同时,将DOM Tree的每一个节点/元素依次写入到预先打开的原始XML文档中,当DOM Tree被遍历完全之后,DOM Tree和原始的XML文档就实现了同步更新。实际中,这个方法极少使用,不过如果你要编程实现自己的XML解析器,这种方法还是有可能用得上的。<BR><BR>方法二:使用XmlDocument类<BR><BR>使用XmlDocument类?JAXP中分明没有这个类呀!是不是作者搞错了?没有错!就是使用XmlDocument类,确切的说,是使用XmlDocument类的write()方法。<BR><BR>在上文已经提到过,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):<BR><BR>public void write (OutputStream out) throws IOException<BR>public void write (Writer out) throws IOException<BR>public void write (Writer out, String encoding) throws IOException<BR><BR>上述三个write()方法的主要作用就是输出DOM Tree中的内容到特定的输出介质中,比如文件输出流、应用程序控制台等等。那么又如何使用上述三个write()方法呢?请看下面的Java程序代码片断:<BR><BR><BR>String name="fancy";<BR>DocumentBuilder parser;<BR>DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();<BR>try <BR>{<BR>parser = factory.newDocumentBuilder();<BR>Document doc = parser.parse("user.xml");<BR>Element newlink=doc.createElement(name);<BR>doc.getDocumentElement().appendChild(newlink);<BR>((XmlDocument)doc).write(new FileOutputStream(new File("xuser1.xml")));<BR>}<BR>catch (Exception e) <BR>{<BR>//to log it <BR>}<BR><BR><BR><BR><BR>在上面的代码中,首先创建了一个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",这时即不存在"汉字问题",输出结果能够正常显示中文字符。<BR><BR>完整的例子请参考下列文件: AddRecord.java(见附件)、user.xml(见附件)。该例子的运行环境为:Windows XP Professional、JDK 1.3.1。为了能够正常编译运行AddRecord.java这个程序,你需要到网址http://xml.apache.org/dist/crimson/去下载Apache Crimson,并将所获取的crimson.jar文件加入到环境变量CLASSPATH中。<BR><BR>注意:<BR><BR>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。<BR><BR>方法三:使用TransformerFactory和Transformer类<BR><BR>在JAXP中所提供的标准的更新原始XML文档的方法就是调用XSLT引擎,亦即使用TransformerFactory和Transformer类。请看下面的Java代码片断:<BR><BR><BR>//首先创建一个DOMSource对象,该构造函数的参数可以是一个Document对象<BR>//doc代表更改后的DOM Tree。<BR>DOMSource doms = new DOMSource (doc);<BR><BR>//创建一个File对象,代表DOM Tree所包含的数据的输出介质,这是一个XML文件。<BR>File f = new File ("XMLOutput.xml");<BR><BR>//创建一个StreamResult对象,该构造函数的参数可以取为File对象。<BR>StreamResult sr = new StreamResult (f);<BR><BR>//下面调用JAXP中的XSLT引擎来实现输出DOM Tree中的数据到XML文件中的功能。<BR>//XSLT引擎的输入为DOMSource对象,输出为StreamResut对象。<BR>try <BR>{<BR>//首先创建一个TransformerFactory对象,再由此创建Transformer对象。Transformer<BR>//类相当于一个XSLT引擎。通常我们使用它来处理XSL文件,但是在这里我们使<BR>//用它来输出XML文档。<BR>TransformerFactory tf=TransformerFactory.newInstance(); <BR>Transformer t=tf.newTransformer ();<BR><BR>//关键的一步, 调用Transformer对象 (XSLT引擎)的transform()方法,该方法的第一<BR>//个参数是DOMSource对象,第二个参数是StreamResult对象。<BR>t.transform(doms,sr); <BR>}<BR>catch (TransformerConfigurationException tce)<BR>{ <BR>System.out.println("Transformer Configuration Exception\n-----");<BR>tce.printStackTrace(); <BR>}<BR>catch (TransformerException te) <BR>{ <BR>System.out.println ("Transformer Exception\n---------"); <BR>te.printStackTrace (); <BR>} <BR><BR><BR><BR><BR>在实际的应用中,我们可以应用传统的DOM API从XML文档中获取DOM Tree,然后根据实际的需求对DOM Tree执行各种操作,得到最终的Document对象,接下来可以由此Document对象创建DOMSource对象,剩下的事情就是照搬上面的代码了,程序运行完毕后, XMLOutput.xml就是你所需要的结果(当然了,你可以随意更改StreamResult类构造函数的参数,指定不同的输出介质,而不必是千篇一律的XML文档)。<BR><BR>这个方法最大的好处在于可以随心所欲的控制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了)。<BR><BR>OutputKeys类<BR><BR>javax.xml.transform.OutputKeys类和java.util.Properties类配合使用,可以控制JAXP的XSLT引擎(Transformer类)输出XML文档的格式。请看下面的代码片断:<BR><BR><BR>//首先创建一个TransformerFactory对象,再由此创建Transformer对象。<BR>TransformerFactory tf=TransformerFactory.newInstance(); <BR>Transformer t=tf.newTransformer ();<BR><BR>//获取Transformser对象的输出属性,亦即XSLT引擎的缺省输出属性,这是一个<BR>//java.util.Properties对象。<BR>Properties properties = t.getOutputProperties(); <BR><BR>//设置新的输出属性:输出字符编码为GB2312,这样可以支持中文字符,XSLT引擎所输出<BR>//的XML文档如果包含了中文字符,可以正常显示,不会出现所谓的"汉字问题"。<BR>//请留意OutputKeys类的字符串常数OutputKeys.ENCODING。<BR>properties.setProperty(OutputKeys.ENCODING,"GB2312"); <BR><BR>/更新XSLT引擎的输出属性。<BR>t.setOutputProperties(properties); <BR><BR>//调用XSLT引擎,按照输出属性中的设置,输出DOM Tree中的内容到输出介质中。<BR>t.transform(DOMSource_Object,StreamResult_Object); <BR><BR><BR><BR><BR>从上面的程序代码,我们不难看出,通过设置XSLT引擎(Transformer类)的输出属性,可以控制DOM Tree中的内容的输出格式,这对于我们定制输出内容是很有帮助的。那么JAXP的XSLT引擎(Transformer类)有那些输出属性可以设置呢? javax.xml.transform.OutputKeys类定义了很多字符串常数,它们都是可以自由设置的输出属性,常用的输出属性如下所示:<BR><BR>public static final java.lang.String METHOD <BR>可以设为"xml"、"html"、"text"等值。 <BR>public static final java.lang.String VERSION<BR>所遵循规范的版本号,如果METHOD设为"xml",那么它的值应该设为"1.0",如果METHOD设为"html",那么它的值应该设为"4.0",如果METHOD设为"text",那么这个输出属性会被忽略。 <BR>public static final java.lang.String ENCODING<BR>设置输出时所采用的编码方式,比如"GB2312"、"UTF-8"等等,如果将其设置为"GB2312",可以解决所谓的"汉字问题"。 <BR>public static final java.lang.String OMIT_XML_DECLARATION<BR>设置输出到XML文档中时是否忽略XML声明,亦即类似于:<BR><?xml version="1.0" standalone="yes" encoding="utf-8" ?><BR>这样的代码。它可选的值有"yes"、"no"。 <BR>public static final java.lang.String INDENT<BR>IDENT设定XSLT引擎在输出XML文档时,是否自动添加额外的空格,它可选的值为"yes"、"no"。 <BR>public static final java.lang.String MEDIA_TYPE<BR>MEDIA_TYPE设定输出文档的MIME类型。 <BR>如果设定XSLT引擎的输出属性呢?下面我们来总结一下:<BR><BR>首先是获取XSLT引擎(Transformer类)的缺省输出属性的集合,这需要使用Transformer类的getOutputProperties()方法,返回值是一个java.util.Properties对象。<BR><BR>Properties properties = transformer.getOutputProperties();<BR>然后是设定新的输出属性,比如:<BR>properties.setProperty(OutputKeys.ENCODING,"GB2312");<BR>properties.setProperty(OutputKeys.METHOD,"html");<BR>properties.setProperty(OutputKeys.VERSION,"4.0");<BR>………………………………………………………<BR><BR>最后是更新XSLT引擎(Transformer类)的缺省输出属性的集合,这需要使用Transformer类的setOutputProperties()方法,参数是一个java.util.Properties对象。<BR><BR>我们编写了一个新的程序,其中应用了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了)。<BR><BR>方法四:使用Xalan XML Serializer<BR><BR>方法四其实是方法三的一个变种,它需要Apache Xalan和Apache Xerces的支持才能够运行。例子代码如下所示:<BR><BR><BR>//首先创建一个DOMSource对象,该构造函数的参数可以是一个Document对象<BR>//doc代表更改后的DOM Tree。<BR>DOMSource domSource = new DOMSource (doc); <BR><BR>//创建一个DOMResult对象,临时保存XSLT引擎的输出结果。<BR>DOMResult domResult = new DOMResult();<BR><BR>//下面调用JAXP中的XSLT引擎来实现输出DOM Tree中的数据到XML文件中的功能。<BR>//XSLT引擎的输入为DOMSource对象,输出为DOMResut对象。<BR>try <BR>{<BR>//首先创建一个TransformerFactory对象,再由此创建Transformer对象。Transformer<BR>//类相当于一个XSLT引擎。通常我们使用它来处理XSL文件,但是在这里我们使<BR>//用它来输出XML文档。<BR>TransformerFactory tf=TransformerFactory.newInstance(); <BR>Transformer t=tf.newTransformer (); <BR><BR>//设置XSLT引擎的属性(必不可少,否则会产生"汉字问题")。<BR>Properties properties = t.getOutputProperties(); <BR>properties.setProperty(OutputKeys.ENCODING,"GB2312");<BR>t.setOutputProperties(properties); <BR><BR>//关键的一步, 调用Transformer对象 (XSLT引擎)的transform()方法,该方法的第一<BR>//个参数是DOMSource对象,第二个参数是DOMResult对象。<BR>t.transform(domSource,domResult);<BR><BR>//创建缺省的Xalan XML Serializer,使用它将临时存放在DOMResult对象<BR>//(domResult)中的内容以输出流的形式输出到输出介质中。<BR>Serializer serializer = SerializerFactory.getSerializer<BR>(OutputProperties.getDefaultMethodProperties("xml"));<BR><BR>//设置Xalan XML Serializer的输出属性,这一步必不可少,否则也可能产生<BR>//所谓的"汉字问题"。<BR>Properties prop=serializer.getOutputFormat();<BR>prop.setProperty("encoding","GB2312");<BR>serializer.setOutputFormat(prop);<BR><BR>//创建一个File对象,代表DOM Tree所包含的数据的输出介质,这是一个XML文件。<BR>File f = new File ("xuser3.xml");<BR><BR>//创建文件输出流对象fos,请留意构造函数的参数。<BR>FileOutputStream fos=new FileOutputStream(f);<BR><BR>//设置Xalan XML Serializer的输出流。<BR>serializer.setOutputStream(fos);<BR><BR>//串行化输出结果。<BR>serializer.asDOMSerializer().serialize(domResult.getNode());<BR>}<BR>catch (Exception tce)<BR>{ <BR>tce.printStackTrace(); <BR>}<BR><BR><BR><BR><BR>这个方法不太常用,而且似乎有点画蛇添足,所以我们就不展开讨论了。完整的例子请参考下列文件: AddRecord4.java(见附件)、user.xml(见附件)。该例子的运行环境为:Windows XP Professional、JDK 1.3.1。为了能够正常编译运行AddRecord4.java这个程序,你需要到网址http://xml.apache.org/dist//去下载安装Apache Xalan和Apache Xerces。<BR><BR>或者是到网址http://java.sun.com/xml/download.html去下载安装Java XML Pack。因为最新的Java XML Pack(Winter 01 版)包含了Apache Xalan和Apache Xerces技术在内。<BR><BR>结论:<BR><BR>本文简略的讨论了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技术,通用性略显不足。<BR><BR>除了上面讨论的四种方法以外,实际上应用别的API(比如JDOM、Castor、XML4J、Oracle XML Parser V2)也有很多办法可以更新XML文档,限于篇幅,在这里就不一一讨论了。<BR><img src ="http://www.blogjava.net/su/aggbug/1587.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/su/" target="_blank">温馨虫窝</a> 2005-03-01 14:36 <a href="http://www.blogjava.net/su/articles/1587.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>