﻿<?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-Timnity的笔记-随笔分类-Java</title><link>http://www.blogjava.net/Timnity/category/6491.html</link><description /><language>zh-cn</language><lastBuildDate>Tue, 27 Feb 2007 08:46:23 GMT</lastBuildDate><pubDate>Tue, 27 Feb 2007 08:46:23 GMT</pubDate><ttl>60</ttl><item><title>巧用JDOM中的XMLOutputter类转换XML文件的编码类型</title><link>http://www.blogjava.net/Timnity/archive/2005/12/29/25953.html</link><dc:creator>Timnity</dc:creator><author>Timnity</author><pubDate>Thu, 29 Dec 2005 13:51:00 GMT</pubDate><guid>http://www.blogjava.net/Timnity/archive/2005/12/29/25953.html</guid><wfw:comment>http://www.blogjava.net/Timnity/comments/25953.html</wfw:comment><comments>http://www.blogjava.net/Timnity/archive/2005/12/29/25953.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Timnity/comments/commentRss/25953.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Timnity/services/trackbacks/25953.html</trackback:ping><description><![CDATA[<P>XML文件的编码不同,使用有的编辑器打开时,其中的中文经常会出现乱码.如何解决这个问题呢?下面我将讲一下如何使用JDOM中的XMLOutputter类进行转换XML文件的编码.</P>
<P>使用XMLOutputter转换XML文件的编码例子代码片断</P>
<P>&nbsp;&nbsp;&nbsp; SAXBuilder builder = new SAXBuilder();<BR>&nbsp;&nbsp;&nbsp; Document doc;<BR>&nbsp;&nbsp;&nbsp; Format format = Format.getPrettyFormat();<BR>&nbsp;&nbsp;&nbsp; format.setEncoding("GB2312");<BR>&nbsp;&nbsp;&nbsp; XMLOutputter outputter = new XMLOutputter();<BR>&nbsp;&nbsp;&nbsp; outputter.setFormat(format);<BR>&nbsp;&nbsp;&nbsp; File file = new File(realPath);<BR>&nbsp;&nbsp;&nbsp; doc = builder.build(file);<BR>&nbsp;&nbsp;&nbsp; String xmlString = outputter.outputString(doc);</P><img src ="http://www.blogjava.net/Timnity/aggbug/25953.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Timnity/" target="_blank">Timnity</a> 2005-12-29 21:51 <a href="http://www.blogjava.net/Timnity/archive/2005/12/29/25953.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JDOM处理XML快速上手[转]</title><link>http://www.blogjava.net/Timnity/archive/2005/12/29/25954.html</link><dc:creator>Timnity</dc:creator><author>Timnity</author><pubDate>Thu, 29 Dec 2005 13:51:00 GMT</pubDate><guid>http://www.blogjava.net/Timnity/archive/2005/12/29/25954.html</guid><wfw:comment>http://www.blogjava.net/Timnity/comments/25954.html</wfw:comment><comments>http://www.blogjava.net/Timnity/archive/2005/12/29/25954.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Timnity/comments/commentRss/25954.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Timnity/services/trackbacks/25954.html</trackback:ping><description><![CDATA[<TABLE cellSpacing=0 cellPadding=0 width="100%" align=center border=0>
<TBODY>
<TR bgColor=#ffffff>
<TD height=0>最近的工作常常要和XML格式的文档或字符串打交道，发现用JDOM来做真是方便。可以实现XML应用程序的快速开发。 
<P>&nbsp;&nbsp;&nbsp; 在 JDOM 中，XML 元素就是 Element 的实例，XML 属性就是 Attribute 的实例，XML 文档本身就是 Document 的实例。<BR>&nbsp;&nbsp;&nbsp; 因为 JDOM 对象就是像 Document、Element 和 Attribute 这些类的直接实例，因此创建一个新 JDOM 对象就如在 Java 语言中使用 new 操作符一样容易。JDOM 的使用是直截了当的。<BR>&nbsp;&nbsp;&nbsp; JDOM 使用标准的 Java 编码模式。只要有可能，它使用 Java new 操作符而不故弄玄虚使用复杂的工厂化模式，使对象操作即便对于初学用户也很方便。<BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; 本文分两步对JDOM的应用加以介绍：XML创建 和 XML解析<BR>一、XML文档创建<BR>&nbsp;&nbsp;&nbsp; 我们由零开始利用JDOM生成一个XML文档。最后的结果(样本文档)看起来象这样：<BR>&nbsp;&nbsp;&nbsp; &lt;?xml version="1.0" encoding="UTF-8"?&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;MyInfo comment="introduce myself"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;name&gt;kingwong&lt;/name&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;sex value="male"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;contact&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;telephone&gt;87654321&lt;/telephone&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/contact&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;/MyInfo&gt;<BR>&nbsp;&nbsp;&nbsp; 1.以 MyInfo 为根元素创建文档<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Element rootElement = new Element("MyInfo");//所有的XML元素都是 Element 的实例。根元素也不例外：）<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Document myDocument = new Document(rootElement);//以根元素作为参数创建Document对象。一个Document只有一个根，即root元素。<BR>&nbsp;&nbsp;&nbsp; 2.给根元素添加属性<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Attribute rootAttri = new Attribute("comment","introduce myself");//创建名为 commnet,值为 introduce myself 的属性。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rootElement.setAttribute(rootAttri);//将刚创建的属性添加到根元素。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这两行代码你也可以合成一行来写，象这样：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rootElement.setAttribute(new Attribute("comment","introduce myself"));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 或者<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rootElement.setAttribute("comment","introduce myself");<BR>&nbsp;&nbsp;&nbsp; 3.添加元素和子元素<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JDOM里子元素是作为 content（内容）添加到父元素里面去的,所谓content就是类似上面样本文档中&lt;name&gt;&lt;/name&gt;之间的东东，即kingwong。罗嗦了点是吧：）<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Element nameElement = new Element("name");//创建 name 元素<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nameElement.addContent("kingwong");//将kingwong作为content添加到name元素<BR>&nbsp;rootElement.addContent(nameElement);//将name元素作为content添加到根元素<BR>&nbsp;<BR>&nbsp;这三行你也可以合为一句，象这样：<BR>&nbsp;rootElement.addContent((Content)(new Element("name").addContent("kingwong")));//因为addContent(Content child)方法返回的是一个Parent接口，而Element类同时继承了Content类和实现了Parent接口，所以我们把它造型成Content。<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 我们用同样的方法添加带属性的子元素&lt;sex value="male"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rootElement.addContent(new Element("sex").setAttribute("value","male"));//注意这里不需要转型，因为addAttribute(String name,String value)返回值就是一个 Element。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 同样的，我们添加&lt;contract /&gt;元素到根元素下，用法上一样，只是稍微复杂了一些：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rootElement.addContent((Content)(new Element("contact").addContent((Content)(new Element("telephone").addContent("87654321")))));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果你对这种简写形式还不太习惯，你完全可以分步来做，就象本节刚开始的时候一样。事实上如果层次比较多，写成分步的形式更清晰些，也不容易出错。<BR>&nbsp;&nbsp;&nbsp; 4.删除子元素<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这个操作比较简单：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rootElement.removeChild("sex");//该方法返回一个布尔值<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 到目前为止，我们学习了一下JDOM文档生成操作。上面建立了一个样本文档，可是我们怎么知道对不对呢？因此需要输出来看一下。我们将JDOM生成的文档输出到控制台，使用 JDOM 的 XMLOutputter 类。<BR>&nbsp;&nbsp;&nbsp; 5.&nbsp; 将 JDOM 转化为 XML 文本<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XMLOutputter xmlOut = new XMLOutputter("&nbsp; ",true);<BR>&nbsp;try {<BR>&nbsp;&nbsp;xmlOut.output(myDocument,System.out);<BR>&nbsp;} catch (IOException e) {<BR>&nbsp;&nbsp;e.printStackTrace();<BR>&nbsp;}<BR>&nbsp;XMLOutputter 有几个格式选项。这里我们已指定希望子元素从父元素缩进两个空格，并且希望元素间有空行。<BR>&nbsp;new XMLOutputter(java.lang.String indent, boolean newlines)这个方法在最新版本中已经不建议使用。JDOM有一个专门的用来定义格式化输出的类：org.jdom.output.Format，如果你没有特殊的要求，有时候使用里面的几个静态方法（应该可以说是预定义格式）如 getPrettyFormat()就可以了。我们把上面的输出格式稍微改一下，就象这样：<BR>&nbsp;XMLOutputter xmlOut = new XMLOutputter(Format.getPrettyFormat());&nbsp; <BR>&nbsp;&nbsp;&nbsp; 6.将JDOM文档转化为其他形式<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XMLOutputter 还可输出到 Writer 或 OutputStream。为了输出JDOM文档到一个文本文件，我们可以这样做：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FileWriter writer = new FileWriter("/some/directory/myFile.xml");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; outputter.output(myDocument, writer);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; writer.close();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XMLOutputter 还可输出到字符串,以便程序后面进行再处理:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Strng outString = xmlOut.outputString(myDocument);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 当然，在输出的时候你不一定要输出所有的整个文档，你可以选择元素进行输出：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xmlOut.output(rootElement.getChild("name"),System.out);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 一句话，JDOM非常灵活方便！如果你想进一步研究JDOM，请到官方网站去看一看：<A href="http://www.jdom.org/">http://www.jdom.org</A></P>
<P>&nbsp;&nbsp;&nbsp; 本节示例源码：<BR>package com.cyberobject.study;</P>
<P>import java.io.IOException;</P>
<P>import org.jdom.Attribute;<BR>import org.jdom.Content;<BR>import org.jdom.Document;<BR>import org.jdom.Element;<BR>import org.jdom.output.Format;<BR>import org.jdom.output.XMLOutputter;</P>
<P>/**<BR>&nbsp;* @author kingwong<BR>&nbsp;*<BR>&nbsp;* TODO To change the template for this generated type comment go to<BR>&nbsp;* Window - Preferences - Java - Code Style - Code Templates<BR>&nbsp;*/<BR>public class TestJDOM {</P>
<P>&nbsp;public static void main(String[] args)<BR>&nbsp;{<BR>&nbsp;&nbsp;Element rootElement = new Element("MyInfo");<BR>&nbsp;&nbsp;Document myDocument = new Document(rootElement);<BR>&nbsp;&nbsp;<BR>//&nbsp;&nbsp;Attribute rootAttri = new Attribute("comment","introduce myself");<BR>//&nbsp;&nbsp;rootElement.setAttribute(rootAttri);<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;rootElement.setAttribute("comment","introduce myself");<BR>&nbsp;&nbsp;//rootElement.setAttribute(new Attribute("comment","introduce myself"));<BR>//&nbsp;&nbsp;Element sexElement = new Element("sex");<BR>//&nbsp;&nbsp;rootElement.addContent(sexElement);<BR>&nbsp;&nbsp;<BR>//&nbsp;&nbsp;Element nameElement = new Element("name");<BR>//&nbsp;&nbsp;nameElement.addContent("kingwong");<BR>//&nbsp;&nbsp;rootElement.addContent(nameElement);<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;rootElement.addContent((Content)(new Element("name").addContent("kingwong")));<BR>&nbsp;&nbsp;rootElement.addContent(new Element("sex").setAttribute("value","male"));<BR>&nbsp;&nbsp;rootElement.addContent((Content)(new Element("contract").addContent((Content)(new Element("telephone").addContent("87654321")))));<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;rootElement.removeChild("sex");<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;XMLOutputter xmlOut = new XMLOutputter(Format.getPrettyFormat());<BR>&nbsp;&nbsp;try {<BR>&nbsp;&nbsp;&nbsp;xmlOut.output(myDocument,System.out);<BR>&nbsp;&nbsp;&nbsp;//xmlOut.output(rootElement.getChild("name"),System.out);<BR>&nbsp;&nbsp;&nbsp;//String outString = xmlOut.outputString(myDocument);<BR>&nbsp;&nbsp;} catch (IOException e) {<BR>&nbsp;&nbsp;&nbsp;e.printStackTrace();<BR>&nbsp;&nbsp;}<BR>&nbsp;}<BR>}</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>二、XML文档解析<BR>&nbsp;&nbsp;&nbsp; JDOM 不光可以很方便的建立XML文档，它的另一个用处是它能够读取并操作现有的 XML 数据。<BR>&nbsp;&nbsp;&nbsp; JDOM的解析器在org.jdom.input.*这个包里，其中的DOMBuilder的功能是将DOM模型的Document解析成JDOM模型的Document；SAXBuilder的功能是从文件或流中解析出符合JDOM模型的XML树。由于我们经常要从一个文件里读取数据，因此我们应该采用后者作为解析工具。<BR>解析一个xml文档，基本可以看成以下几个步骤：<BR>&nbsp;&nbsp;&nbsp; 1.实例化一个合适的解析器对象<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 本例中我们使用SAXBuilder:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SAXBuilder sb = new SAXBuilder();<BR>&nbsp;&nbsp;&nbsp; 2.以包含XML数据的文件为参数，构建一个文档对象myDocument<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Document myDocument = sb.build(/some/directory/myFile.xml);<BR>&nbsp;&nbsp;&nbsp; 3.获到根元素<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Element rootElement = myDocument.getRootElement();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 一旦你获取了根元素，你就可以很方便地对它下面的子元素进行操作了，下面对Element对象的一些常用方法作一下简单说明：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getChild("childname") 返回指定名字的子节点,如果同一级有多个同名子节点，则只返回第一个；如果没有返回null值。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getChildren("childname") 返回指定名字的子节点List集合。这样你就可以遍历所有的同一级同名子节点。 <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getAttributeValue("name") 返回指定属性名字的值。如果没有该属性则返回null,有该属性但是值为空，则返回空字符串。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getChildText("childname") 返回指定子节点的内容文本值。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getText() 返回该元素的内容文本值。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 还有其他没有罗列出来的方法，如果需要的话，可以随时查阅JDOM的在线文档：<A href="http://www.jdom.org/docs/apidocs/index.html">http://www.jdom.org/docs/apidocs/index.html</A>。当然你可以在你需要的地方添加、删除元素操作，还记得上面的创建XML的方法吗？呵呵~~~<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 学习新东东还是从实例学起最为快捷，下面简单举个例子，就以上面的XML样本代码来学习JDOM的XML解析。本例中读取了样本XML文件里一些属性和content，最后我们还在contact元素里插入了一个新元素&lt;email value="<A href="mailto:wanghua@cyberobject.com">wanghua@cyberobject.com</A>" /&gt;。尽管我们实现了对于XML的基本操作，细心的朋友可能会<BR>有疑问：如果XML文档的层次稍微复杂一些，如果嵌套多达几十上百层的话（开个玩笑），如果靠这样从根元素一级一级地通过getChild("childname")来访问子元素的话，将会非常痛苦！是的，的确是这样，但是我们有另一个有力的工具XPath，为什么不用呢？这是后话！先卖个关子（手敲累啦，下回吧，呵呵）。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>/*<BR>&nbsp;* Created on 2004-8-21<BR>&nbsp;*<BR>&nbsp;* TODO To change the template for this generated file go to<BR>&nbsp;* Window - Preferences - Java - Code Style - Code Templates<BR>&nbsp;*/<BR>package com.cyberobject.study;</P>
<P>import org.jdom.Document;<BR>import org.jdom.Element;<BR>import org.jdom.input.SAXBuilder;<BR>import org.jdom.output.Format;<BR>import org.jdom.output.XMLOutputter;</P>
<P>/**<BR>&nbsp;* @author kingwong<BR>&nbsp;*<BR>&nbsp;* TODO To change the template for this generated type comment go to<BR>&nbsp;* Window - Preferences - Java - Code Style - Code Templates<BR>&nbsp;*/<BR>public class TestJDOM2 {<BR>&nbsp;public static void main(String[] args){<BR>&nbsp;SAXBuilder sb = new SAXBuilder();<BR>&nbsp;&nbsp;&nbsp; try<BR>&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp; Document doc = sb.build("myFile.xml");<BR>&nbsp;&nbsp;Element root = doc.getRootElement();<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;String str1 = root.getAttributeValue("comment");<BR>&nbsp;&nbsp;System.out.println("Root Element's comment attribute is : " + str1);<BR>&nbsp;&nbsp;String str2 = root.getChild("sex").getAttributeValue("value");<BR>&nbsp;&nbsp;System.out.println("sex Element's value attribute is : " + str2);<BR>&nbsp;&nbsp;String str3 = root.getChildText("name");<BR>&nbsp;&nbsp;System.out.println("name Element's content is :" + str3);<BR>&nbsp;&nbsp;String str4 = root.getChild("contact").getChildText("telephone");<BR>&nbsp;&nbsp;System.out.println("contact Element's telephone subelement content is : " + str4 + "\n");<BR>&nbsp;&nbsp;Element inputElement = root.getChild("contact");&nbsp;<BR>&nbsp;&nbsp;inputElement.addContent(new Element("email").setAttribute("value","<A href="mailto:wanghua@cyberobject.com">wanghua@cyberobject.com</A>"));<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;XMLOutputter xmlOut = new XMLOutputter(Format.getPrettyFormat());<BR>&nbsp;&nbsp;&nbsp;&nbsp; String outStr = xmlOut.outputString(root);<BR>&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(outStr);<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; catch(Exception e)<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.printStackTrace();<BR>&nbsp;&nbsp;&nbsp; }<BR>}<BR>}<BR></P></TD></TR></TBODY></TABLE><img src ="http://www.blogjava.net/Timnity/aggbug/25954.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Timnity/" target="_blank">Timnity</a> 2005-12-29 21:51 <a href="http://www.blogjava.net/Timnity/archive/2005/12/29/25954.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JAR 文件格式的强大功能</title><link>http://www.blogjava.net/Timnity/archive/2005/12/29/25943.html</link><dc:creator>Timnity</dc:creator><author>Timnity</author><pubDate>Thu, 29 Dec 2005 13:38:00 GMT</pubDate><guid>http://www.blogjava.net/Timnity/archive/2005/12/29/25943.html</guid><wfw:comment>http://www.blogjava.net/Timnity/comments/25943.html</wfw:comment><comments>http://www.blogjava.net/Timnity/archive/2005/12/29/25943.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Timnity/comments/commentRss/25943.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Timnity/services/trackbacks/25943.html</trackback:ping><description><![CDATA[<P style="TEXT-INDENT: 2em">大多数 Java 程序员都熟悉对 JAR 文件的基本操作。但是只有少数程序员了解 JAR 文件格式的强大功能。在本文中，作者探讨了 JAR 格式的许多功能和优势，包括打包、可执行的 JAR 文件、安全性和索引。 
<P style="TEXT-INDENT: 2em"><STRONG>JAR 文件是什么？</STRONG> 
<P style="TEXT-INDENT: 2em">JAR 文件格式以流行的 ZIP 文件格式为基础，用于将许多个文件聚集为一个文件。与 ZIP 文件不同的是，JAR 文件不仅用于压缩和发布，而且还用于部署和封装库、组件和插件程序，并可被像编译器和 JVM 这样的工具直接使用。在 JAR 中包含特殊的文件，如 manifests 和部署描述符，用来指示工具如何处理特定的 JAR。 
<P style="TEXT-INDENT: 2em">一个 JAR 文件可以用于： 
<OL>
<LI>用于发布和使用类库 
<LI>作为应用程序和扩展的构建单元 
<LI>作为组件、applet 或者插件程序的部署单位 
<LI>用于打包与组件相关联的辅助资源 </LI></OL>
<P style="TEXT-INDENT: 2em">JAR 文件格式提供了许多优势和功能，其中很多是传统的压缩格式如 ZIP 或者 TAR 所没有提供的。它们包括： 
<P style="TEXT-INDENT: 2em"><STRONG>安全性</STRONG>。 可以对 JAR 文件内容加上数字化签名。这样，能够识别签名的工具就可以有选择地为您授予软件安全特权，这是其他文件做不到的，它还可以检测代码是否被篡改过。 
<P style="TEXT-INDENT: 2em"><STRONG>减少下载时间</STRONG>。 如果一个 applet 捆绑到一个 JAR 文件中，那么浏览器就可以在一个 HTTP 事务中下载这个 applet 的类文件和相关的资源，而不是对每一个文件打开一个新连接。 
<P style="TEXT-INDENT: 2em"><STRONG>压缩</STRONG>。JAR 格式允许您压缩文件以提高存储效率。 
<P style="TEXT-INDENT: 2em"><STRONG>传输平台扩展</STRONG>。 Java 扩展框架(Java Extensions Framework)提供了向 Java 核心平台添加功能的方法，这些扩展是用 JAR 文件打包的(Java 3D 和 JavaMail 就是由 Sun 开发的扩展例子)。 
<P style="TEXT-INDENT: 2em"><STRONG>包密封</STRONG>。 存储在 JAR 文件中的包可以选择进行密封，以增强版本一致性和安全性。密封一个包意味着包中的所有类都必须在同一 JAR 文件中找到。 
<P style="TEXT-INDENT: 2em"><STRONG>包版本控制</STRONG>。 一个 JAR 文件可以包含有关它所包含的文件的数据，如厂商和版本信息。 
<P style="TEXT-INDENT: 2em"><STRONG>可移植性</STRONG>。 处理 JAR 文件的机制是 Java 平台核心 API 的标准部分。 
<P style="TEXT-INDENT: 2em">压缩的和未压缩的 JAR 
<P style="TEXT-INDENT: 2em">jar 工具(有关细节参阅 jar 工具)在默认情况下压缩文件。未压缩的 JAR 文件一般可以比压缩过的 JAR 文件更快地装载，因为在装载过程中要解压缩文件，但是未压缩的文件在网络上的下载时间可能更长。 
<P style="TEXT-INDENT: 2em"><STRONG>META-INF 目录</STRONG> 
<P style="TEXT-INDENT: 2em">大多数 JAR 文件包含一个 META-INF 目录，它用于存储包和扩展的配置数据，如安全性和版本信息。Java 2 平台识别并解释 META-INF 目录中的下述文件和目录，以便配置应用程序、扩展和类装载器： 
<P style="TEXT-INDENT: 2em"><STRONG>MANIFEST.MF</STRONG>。 这个 manifest 文件定义了与扩展和包相关的数据。 
<P style="TEXT-INDENT: 2em"><STRONG>INDEX.LIST</STRONG>。 这个文件由 jar 工具的新选项 -i 生成，它包含在应用程序或者扩展中定义的包的位置信息。它是 JarIndex 实现的一部分，并由类装载器用于加速类装载过程。 
<P style="TEXT-INDENT: 2em"><STRONG>xxx.SF</STRONG>。 这是 JAR 文件的签名文件。占位符 xxx 标识了签名者。 
<P style="TEXT-INDENT: 2em"><STRONG>xxx.DSA</STRONG>。 与签名文件相关联的签名程序块文件，它存储了用于签名 JAR 文件的公共签名。 
<P style="TEXT-INDENT: 2em"><STRONG>jar 工具</STRONG> 
<P style="TEXT-INDENT: 2em">为了用 JAR 文件执行基本的任务，要使用作为Java Development Kit 的一部分提供的 Java Archive Tool (jar 工具)。用 jar 命令调用 jar 工具。表 1 显示了一些常见的应用： 
<P style="TEXT-INDENT: 2em"><STRONG>表 1. 常见的 jar 工具用法 功能 命令</STRONG> 
<P style="TEXT-INDENT: 2em">用一个单独的文件创建一个 JAR 文件 jar cf jar-file input-file... 
<P style="TEXT-INDENT: 2em">用一个目录创建一个 JAR 文件 jar cf jar-file dir-name 
<P style="TEXT-INDENT: 2em">创建一个未压缩的 JAR 文件 jar cf0 jar-file dir-name 
<P style="TEXT-INDENT: 2em">更新一个 JAR 文件 jar uf jar-file input-file... 
<P style="TEXT-INDENT: 2em">查看一个 JAR 文件的内容 jar tf jar-file 
<P style="TEXT-INDENT: 2em">提取一个 JAR 文件的内容 jar xf jar-file 
<P style="TEXT-INDENT: 2em">从一个 JAR 文件中提取特定的文件 jar xf jar-file archived-file... 
<P style="TEXT-INDENT: 2em">运行一个打包为可执行 JAR 文件的应用程序 java -jar app.jar 
<P style="TEXT-INDENT: 2em"><STRONG>可执行的 JAR</STRONG> 
<P style="TEXT-INDENT: 2em">一个可执行的 jar 文件是一个自包含的 Java 应用程序，它存储在特别配置的JAR 文件中，可以由 JVM 直接执行它而无需事先提取文件或者设置类路径。要运行存储在非可执行的 JAR 中的应用程序，必须将它加入到您的类路径中，并用名字调用应用程序的主类。但是使用可执行的 JAR 文件，我们可以不用提取它或者知道主要入口点就可以运行一个应用程序。可执行 JAR 有助于方便发布和执行 Java 应用程序。 
<P style="TEXT-INDENT: 2em"><STRONG>创建可执行 JAR</STRONG> 
<P style="TEXT-INDENT: 2em">创建一个可执行 JAR 很容易。首先将所有应用程序代码放到一个目录中。假设应用程序中的主类是 com.mycompany.myapp.Sample。您要创建一个包含应用程序代码的 JAR 文件并标识出主类。为此，在某个位置(不是在应用程序目录中)创建一个名为 manifest 的文件，并在其中加入以下一行： 
<P style="TEXT-INDENT: 2em">Main-Class: com.mycompany.myapp.Sample 
<P style="TEXT-INDENT: 2em">然后，像这样创建 JAR 文件： 
<P style="TEXT-INDENT: 2em">jar cmf manifest ExecutableJar.jar application-dir 
<P style="TEXT-INDENT: 2em">所要做的就是这些了 -- 现在可以用 java -jar 执行这个 JAR 文件 ExecutableJar.jar。 
<P style="TEXT-INDENT: 2em">一个可执行的 JAR 必须通过 menifest 文件的头引用它所需要的所有其他从属 JAR。如果使用了 -jar 选项，那么环境变量 CLASSPATH 和在命令行中指定的所有类路径都被 JVM 所忽略。 
<P style="TEXT-INDENT: 2em"><STRONG>启动可执行 JAR</STRONG> 
<P style="TEXT-INDENT: 2em">既然我们已经将自己的应用程序打包到了一个名为 ExecutableJar.jar 的可执行 JAR 中了，那么我们就可以用下面的命令直接从文件启动这个应用程序： 
<P style="TEXT-INDENT: 2em">java -jar ExecutableJar.jar 
<P style="TEXT-INDENT: 2em"><STRONG>包密封</STRONG> 
<P style="TEXT-INDENT: 2em">密封 JAR 文件中的一个包意味着在这个包中定义的所有类都必须在同一个 JAR 文件中找到。这使包的作者可以增强打包类之间的版本一致性。密封还提供了防止代码篡改的手段。 
<P style="TEXT-INDENT: 2em">要密封包，需要在 JAR 的 manifest 文件中为包添加一个 Name 头，然后加上值为“true”的 Sealed 头。与可执行的 JAR 一样，可以在创建 JAR 时，通过指定一个具有适当头元素的 manifest 文件密封一个 JAR，如下所示： 
<P style="TEXT-INDENT: 2em">Name: com/samplePackage/ 
<P style="TEXT-INDENT: 2em">Sealed: true 
<P style="TEXT-INDENT: 2em">Name 头标识出包的相对路径名。它以一个“/”结束以与文件名区别。在 Name 头后面第一个空行之前的所有头都作用于在 Name 头中指定的文件或者包。在上述例子中，因为 Sealed 头出现在 Name 头后并且中间没有空行，所以 Sealed 头将被解释为只应用到包 com/samplePackage 上。 
<P style="TEXT-INDENT: 2em">如果试图从密封包所在的 JAR 文件以外的其他地方装载密封包中的一个类，那么 JVM 将抛出一个 SecurityException。 
<P style="TEXT-INDENT: 2em"><STRONG>扩展打包</STRONG> 
<P style="TEXT-INDENT: 2em">扩展为 Java 平台增加了功能，在 JAR 文件格式中已经加入了扩展机制。扩展机制使得 JAR 文件可以通过 manifest 文件中的 Class-Path 头指定所需要的其他 JAR 文件。 
<P style="TEXT-INDENT: 2em">假设 extension1.jar 和 extension2.jar 是同一个目录中的两个 JAR 文件，extension1.jar 的 manifest 文件包含以下头： 
<P style="TEXT-INDENT: 2em">Class-Path: extension2.jar 
<P style="TEXT-INDENT: 2em">这个头表明 extension2.jar 中的类是 extension1.jar 中的类的扩展类。extension1.jar 中的类可以调用 extension2.jar 中的类，并且不要求 extension2.jar 处在类路径中。 
<P style="TEXT-INDENT: 2em">在装载使用扩展机制的 JAR 时，JVM 会高效而自动地将在Class-Path 头中引用的 JAR 添加到类路径中。不过，扩展 JAR 路径被解释为相对路径，所以一般来说，扩展 JAR 必须存储在引用它的 JAR 所在的同一目录中。 
<P style="TEXT-INDENT: 2em">例如，假设类 ExtensionClient 引用了类 ExtensionDemo,它捆绑在一个名为 ExtensionClient.jar 的 JAR 文件中，而类 ExtensionDemo 则捆绑在 ExtensionDemo.jar 中。为了使 ExtensionDemo.jar 可以成为扩展，必须将 ExtensionDemo.jar 列在 ExtensionClient.jar 的 manifest 的 Class-Path 头中，如下所示： 
<P style="TEXT-INDENT: 2em">Manifest-Version: 1.0 
<P style="TEXT-INDENT: 2em">Class-Path: ExtensionDemo.jar 
<P style="TEXT-INDENT: 2em">在这个 manifest 中 Class-Path 头的值是没有指定路径的 ExtensionDemo.jar，表明 ExtensionDemo.jar 与 ExtensionClient JAR 文件处在同一目录中。 
<P style="TEXT-INDENT: 2em"><STRONG>JAR 文件中的安全性</STRONG> 
<P style="TEXT-INDENT: 2em">JAR 文件可以用 jarsigner 工具或者直接通过 java.security API 签名。一个签名的 JAR 文件与原来的 JAR 文件完全相同，只是更新了它的 manifest，并在 META-INF 目录中增加了两个文件，一个签名文件和一个签名块文件。 
<P style="TEXT-INDENT: 2em">JAR 文件是用一个存储在 Keystore 数据库中的证书签名的。存储在 keystore 中的证书有密码保护，必须向 jarsigner 工具提供这个密码才能对 JAR 文件签名。 
<P style="TEXT-INDENT: 2em" align=center><STRONG>图 1. Keystore 数据库</STRONG> 
<P style="TEXT-INDENT: 2em">
<CENTER><IMG style="CURSOR: pointer" onclick=javascript:window.open(this.src); src="http://cimg.163.com/catchpic/3/3D/3D5A6A33CE83B305CAB14F212F657CD5.gif" onload="javascript:if(this.width>500)this.style.width=500;" border=0></CENTER>
<P style="TEXT-INDENT: 2em">JAR 的每一位签名者都由在 JAR 文件的 META-INF 目录中的一个具有 .SF 扩展名的签名文件表示。这个文件的格式类似于 manifest 文件 -- 一组 RFC-822 头。如下所示，它的组成包括一个主要部分，它包括了由签名者提供的信息、但是不特别针对任何特定的 JAR 文件项，还有一系列的单独的项，这些项也必须包含在 menifest 文件中。在验证一个签名的 JAR 时，将签名文件的摘要值与对 JAR 文件中的相应项计算的摘要值进行比较。 
<P style="TEXT-INDENT: 2em"><STRONG>清单 1. 签名 JAR 中的 Manifest 和 signature 文件</STRONG> 
<P style="TEXT-INDENT: 2em">Contents of signature file META-INF/MANIFEST.MF 
<P style="TEXT-INDENT: 2em">Manifest-Version: 1.0 
<P style="TEXT-INDENT: 2em">Created-By: 1.3.0 (Sun Microsystems Inc.) 
<P style="TEXT-INDENT: 2em">Name: Sample.java 
<P style="TEXT-INDENT: 2em">SHA1-Digest: 3+DdYW8INICtyG8ZarHlFxX0W6g= 
<P style="TEXT-INDENT: 2em">Name: Sample.class 
<P style="TEXT-INDENT: 2em">SHA1-Digest: YJ5yQHBZBJ3SsTNcHJFqUkfWEmI= 
<P style="TEXT-INDENT: 2em">Contents of signature file META-INF/JAMES.SF 
<P style="TEXT-INDENT: 2em">Signature-Version: 1.0 
<P style="TEXT-INDENT: 2em">SHA1-Digest-Manifest: HBstZOJBuuTJ6QMIdB90T8sjaOM= 
<P style="TEXT-INDENT: 2em">Created-By: 1.3.0 (Sun Microsystems Inc.) 
<P style="TEXT-INDENT: 2em">Name: Sample.java 
<P style="TEXT-INDENT: 2em">SHA1-Digest: qipMDrkurQcKwnyIlI3Jtrnia8Q= 
<P style="TEXT-INDENT: 2em">Name: Sample.class 
<P style="TEXT-INDENT: 2em">SHA1-Digest: pT2DYby8QXPcCzv2NwpLxd8p4G4= 
<P style="TEXT-INDENT: 2em"><STRONG>数字签名</STRONG> 
<P style="TEXT-INDENT: 2em">一个数字签名是.SF 签名文件的已签名版本。数字签名文件是二进制文件，并且与 .SF 文件有相同的文件名，但是扩展名不同。根据数字签名的类型 -- RSA、DSA 或者 PGP -- 以及用于签名 JAR 的证书类型而有不同的扩展名。 
<P style="TEXT-INDENT: 2em"><STRONG>Keystore</STRONG> 
<P style="TEXT-INDENT: 2em">要签名一个 JAR 文件，必须首先有一个私钥。私钥及其相关的公钥证书存储在名为 keystores 的、有密码保护的数据库中。JDK 包含创建和修改 keystores 的工具。keystore 中的每一个密钥都可以用一个别名标识，它通常是拥有这个密钥的签名者的名字。 
<P style="TEXT-INDENT: 2em">所有 keystore 项(密钥和信任的证书项)都是用唯一别名访问的。别名是在用 keytool -genkey 命令生成密钥对(公钥和私钥)并在 keystore 中添加项时指定的。之后的 keytool 命令必须使用同样的别名引用这一项。 
<P style="TEXT-INDENT: 2em">例如，要用别名“james”生成一个新的公钥/私钥对并将公钥包装到自签名的证书中，要使用下述命令： 
<P style="TEXT-INDENT: 2em">keytool -genkey -alias james -keypass jamespass 
<P style="TEXT-INDENT: 2em">-validity 80 -keystore jamesKeyStore 
<P style="TEXT-INDENT: 2em">-storepass jamesKeyStorePass 
<P style="TEXT-INDENT: 2em">这个命令序列指定了一个初始密码“jamespass”，后续的命令在访问 keystore “jamesKeyStore”中与别名“james”相关联的私钥时，就需要这个密码。如果 keystore“jamesKeyStore”不存在，则 keytool 会自动创建它。 
<P style="TEXT-INDENT: 2em"><STRONG>jarsigner 工具</STRONG> 
<P style="TEXT-INDENT: 2em">jarsigner 工具使用 keystore 生成或者验证 JAR 文件的数字签名。 
<P style="TEXT-INDENT: 2em">假设像上述例子那样创建了 keystore “jamesKeyStore”，并且它包含一个别名为“james”的密钥，可以用下面的命令签名一个 JAR 文件： 
<P style="TEXT-INDENT: 2em">jarsigner -keystore jamesKeyStore -storepass jamesKeyStorePass 
<P style="TEXT-INDENT: 2em">-keypass jamespass -signedjar SSample.jar Sample.jar james 
<P style="TEXT-INDENT: 2em">这个命令用密码“jamesKeyStorePass”从名为“jamesKeyStore”的 keystore 中提出别名为“james”、密码为“jamespass”的密钥，并对 Sample.jar 文件签名、创建一个签名的 JAR -- SSample.jar。 
<P style="TEXT-INDENT: 2em">jarsigner 工具还可以验证一个签名的 JAR 文件，这种操作比签名 JAR 文件要简单得多，只需执行以下命令： 
<P style="TEXT-INDENT: 2em">jarsigner -verify SSample.jar 
<P style="TEXT-INDENT: 2em">如果签名的 JAR 文件没有被篡改过，那么 jarsigner 工具就会告诉您 JAR 通过验证了。否则，它会抛出一个 SecurityException， 表明哪些文件没有通过验证。 
<P style="TEXT-INDENT: 2em">还可以用 java.util.jar 和 java.security API 以编程方式签名 JAR(有关细节参阅参考资料)。也可以使用像 Netscape Object Signing Tool 这样的工具。 
<P style="TEXT-INDENT: 2em"><STRONG>JAR 索引</STRONG> 
<P style="TEXT-INDENT: 2em">如果一个应用程序或者 applet 捆绑到多个 JAR 文件中，那么类装载器就使用一个简单的线性搜索算法搜索类路径中的每一个元素，这使类装载器可能要下载并打开许多个 JAR 文件，直到找到所要的类或者资源。如果类装载器试图寻找一个不存在的资源，那么在应用程序或者 applet 中的所有 JAR 文件都会下载。对于大型的网络应用程序和 applet，这会导致启动缓慢、响应迟缓并浪费带宽。 
<P style="TEXT-INDENT: 2em">从 JDK 1.3 以后，JAR 文件格式开始支持索引以优化网络应用程序中类的搜索过程，特别是 applet。JarIndex 机制收集在 applet 或者应用程序中定义的所有 JAR 文件的内容，并将这些信息存储到第一个 JAR 文件中的索引文件中。下载了第一个 JAR 文件后，applet 类装载器将使用收集的内容信息高效地装载 JAR 文件。这个目录信息存储在根 JAR 文件的 META-INF 目录中的一个名为 INDEX.LIST 的简单文本文件中。 
<P style="TEXT-INDENT: 2em"><STRONG>创建一个 JarIndex</STRONG> 
<P style="TEXT-INDENT: 2em">可以通过在 jar 命令中指定 -i 选项创建一个 JarIndex。假设我们的目录结构如下图所示： 
<P style="TEXT-INDENT: 2em" align=center><STRONG>图 2. JarIndex</STRONG> 
<P style="TEXT-INDENT: 2em">
<CENTER><IMG style="CURSOR: pointer" onclick=javascript:window.open(this.src); src="http://cimg.163.com/catchpic/3/39/390B2F53CE4352348363CAAAFB8671DB.gif" onload="javascript:if(this.width>500)this.style.width=500;" border=0></CENTER>
<P style="TEXT-INDENT: 2em">您将使用下述命令为 JarIndex_Main.jar、JarIndex_test.jar 和 JarIndex_test1.jar 创建一个索引文件： 
<P style="TEXT-INDENT: 2em">jar -i JarIndex_Main.jar JarIndex_test.jar SampleDir/JarIndex_test1.jar 
<P style="TEXT-INDENT: 2em">INDEX.LIST 文件的格式很简单，包含每个已索引的 JAR 文件中包含的包或者类的名字，如清单 2 所示： 
<P style="TEXT-INDENT: 2em"><STRONG>清单 2. JarIndex INDEX.LIST 文件示例</STRONG> 
<P style="TEXT-INDENT: 2em">JarIndex-Version: 1.0 
<P style="TEXT-INDENT: 2em">JarIndex_Main.jar 
<P style="TEXT-INDENT: 2em">sp 
<P style="TEXT-INDENT: 2em">JarIndex_test.jar 
<P style="TEXT-INDENT: 2em">Sample 
<P style="TEXT-INDENT: 2em">SampleDir/JarIndex_test1.jar 
<P style="TEXT-INDENT: 2em">org 
<P style="TEXT-INDENT: 2em">org/apache 
<P style="TEXT-INDENT: 2em">org/apache/xerces 
<P style="TEXT-INDENT: 2em">org/apache/xerces/framework 
<P style="TEXT-INDENT: 2em">org/apache/xerces/framework/xml4j 
<P style="TEXT-INDENT: 2em"><STRONG>结束语</STRONG> 
<P style="TEXT-INDENT: 2em">JAR 格式远远超出了一种压缩格式，它有许多可以改进效率、安全性和组织 Java 应用程序的功能。因为这些功能已经建立在核心平台 -- 包括编译器和类装载器 -- 中了，所以开发人员可以利用 JAR 文件格式的能力简化和改进开发和部署过程。 
<P style="TEXT-INDENT: 2em">（关键字：java jar） 
<P style="TEXT-INDENT: 2em">（来源：csdn.net）</P><img src ="http://www.blogjava.net/Timnity/aggbug/25943.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Timnity/" target="_blank">Timnity</a> 2005-12-29 21:38 <a href="http://www.blogjava.net/Timnity/archive/2005/12/29/25943.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>