﻿<?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简析XML</title><link>http://www.blogjava.net/lizhuxin/category/33758.html</link><description>☆</description><language>zh-cn</language><lastBuildDate>Thu, 14 Aug 2008 06:05:44 GMT</lastBuildDate><pubDate>Thu, 14 Aug 2008 06:05:44 GMT</pubDate><ttl>60</ttl><item><title>Java与XML联合编程之DOM篇</title><link>http://www.blogjava.net/lizhuxin/articles/221937.html</link><dc:creator>☆</dc:creator><author>☆</author><pubDate>Thu, 14 Aug 2008 04:15:00 GMT</pubDate><guid>http://www.blogjava.net/lizhuxin/articles/221937.html</guid><wfw:comment>http://www.blogjava.net/lizhuxin/comments/221937.html</wfw:comment><comments>http://www.blogjava.net/lizhuxin/articles/221937.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lizhuxin/comments/commentRss/221937.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lizhuxin/services/trackbacks/221937.html</trackback:ping><description><![CDATA[<span style="font-size: 12pt">Java与XML联合编程之DOM篇:<br />
</span><br />
&nbsp;
<p style="margin-bottom: 12pt; line-height: 14.95pt; text-align: left" align="left"><strong><span style="font-size: 9.5pt; font-family: 宋体">DOM</span></strong><strong><span style="font-size: 9.5pt; font-family: 宋体">初步</span></strong><span style="font-size: 9.5pt; font-family: 宋体"> <br />
DOM</span><span style="font-size: 9.5pt; font-family: 宋体">是Document Object Model的缩写，即文档对象模型。前面说过，XML将数据组织为一颗树，所以DOM就是对这颗树的一个对象描叙。通俗的说，就是通过解析XML文档，为XML文档在逻辑上建立一个树模型，树的节点是一个个对象。我们通过存取这些对象就能够存取XML文档的内容。 <br />
<br />
下面我们来看一个简单的例子，看看在DOM中，我们是如何来操作一个XML文档的。 <br />
<br />
这是一个XML文档，也是我们要操作的对象：</span></p>
<table style="width: 435pt" cellspacing="0" cellpadding="0" width="580" border="1">
    <tbody>
        <tr>
            <td style="padding-right: 0cm; padding-left: 0cm; background: #e6e6e6; padding-bottom: 0cm; padding-top: 0cm">
            <p style="line-height: 10.85pt; text-align: left" align="left"><span style="font-size: 7.5pt; color: black; font-family: Verdana">&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />
            &lt;messages&gt;<br />
            &lt;message&gt;Good-bye serialization, hello Java!&lt;/message&gt;<br />
            &lt;/messages&gt;</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="margin-bottom: 12pt; line-height: 14.95pt; text-align: left" align="left"><span style="font-size: 9.5pt; font-family: 宋体"><br />
</span><span style="font-size: 9.5pt; font-family: 宋体">下面，我们需要把这个文档的内容解析到一个个的Java对象中去供程序使用，利用JAXP，我们只需几行代码就能做到这一点。首先，我们需要建立一个解析器工厂，以利用这个工厂来获得一个具体的解析器对象：</span></p>
<table style="width: 435pt" cellspacing="0" cellpadding="0" width="580" border="1">
    <tbody>
        <tr>
            <td style="padding-right: 0cm; padding-left: 0cm; background: #e6e6e6; padding-bottom: 0cm; padding-top: 0cm">
            <p style="line-height: 10.85pt; text-align: left" align="left"><span style="font-size: 7.5pt; color: black; font-family: Verdana">DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="margin-bottom: 12pt; line-height: 14.95pt; text-align: left" align="left"><span style="font-size: 9.5pt; font-family: 宋体"><br />
</span><span style="font-size: 9.5pt; font-family: 宋体">我们在这里使用DocumentBuilderFacotry的目的是为了创建与具体解析器无关的程序，当DocumentBuilderFactory类的静态方法newInstance()被调用时，它根据一个系统变量来决定具体使用哪一个解析器。又因为所有的解析器都服从于JAXP所定义的接口，所以无论具体使用哪一个解析器，代码都是一样的。所以当在不同的解析器之间进行切换时，只需要更改系统变量的值，而不用更改任何代码。这就是工厂所带来的好处。这个工厂模式的具体实现，可以参看下面的类图。</span></p>
<table style="width: 435pt" cellspacing="0" cellpadding="0" width="580" border="1">
    <tbody>
        <tr>
            <td style="padding-right: 0cm; padding-left: 0cm; background: #e6e6e6; padding-bottom: 0cm; padding-top: 0cm">
            <p style="line-height: 10.85pt; text-align: left" align="left"><span style="font-size: 7.5pt; color: black; font-family: Verdana">DocumentBuilder db = dbf.newDocumentBuilder();</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="margin-bottom: 12pt; line-height: 14.95pt; text-align: left" align="left"><span style="font-size: 9.5pt; font-family: 宋体"><br />
</span><span style="font-size: 9.5pt; font-family: 宋体">当获得一个工厂对象后，使用它的静态方法newDocumentBuilder()方法可以获得一个DocumentBuilder对象，这个对象代表了具体的DOM解析器。但具体是哪一种解析器，微软的或者IBM的，对于程序而言并不重要。 <br />
<br />
然后，我们就可以利用这个解析器来对XML文档进行解析了：</span></p>
<table style="width: 435pt" cellspacing="0" cellpadding="0" width="580" border="1">
    <tbody>
        <tr>
            <td style="padding-right: 0cm; padding-left: 0cm; background: #e6e6e6; padding-bottom: 0cm; padding-top: 0cm">
            <p style="line-height: 10.85pt; text-align: left" align="left"><span style="font-size: 7.5pt; color: black; font-family: Verdana">Document doc = db.parse("c:/xml/message.xml");</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="margin-bottom: 12pt; line-height: 14.95pt; text-align: left" align="left"><span style="font-size: 9.5pt; font-family: 宋体"><br />
DocumentBuilder</span><span style="font-size: 9.5pt; font-family: 宋体">的parse()方法接受一个XML文档名作为输入参数，返回一个Document对象，这个Document对象就代表了一个XML文档的树模型。以后所有的对XML文档的操作，都与解析器无关，直接在这个Document对象上进行操作就可以了。而具体对Document操作的方法，就是由DOM所定义的了</span></p>
<p style="margin-bottom: 12pt; line-height: 14.95pt; text-align: left" align="left"><span style="font-size: 9.5pt; font-family: 宋体"><br />
Jaxp</span><span style="font-size: 9.5pt; font-family: 宋体">支持W3C所推荐的DOM 2。如果你对DOM很熟悉，那么下面的内容就很简单了：只需要按照DOM的规范来进行方法调用就可以。当然，如果你对DOM不清楚，也不用着急，后面我们会有详细的介绍。在这儿，你所要知道并牢记的是：DOM是用来描叙XML文档中的数据的模型，引入DOM的全部原因就是为了用这个模型来操作XML文档的中的数据。DOM规范中定义有节点（即对象）、属性和方法，我们通过这些节点的存取来存取XML的数据。 <br />
<br />
从上面得到的Document对象开始，我们就可以开始我们的DOM之旅了。使用Document对象的getElementsByTagName()方法，我们可以得到一个NodeList对象，一个Node对象代表了一个XML文档中的一个标签元素，而NodeList对象，观其名而知其意，所代表的是一个Node对象的列表：</span></p>
<table style="width: 435pt" cellspacing="0" cellpadding="0" width="580" border="1">
    <tbody>
        <tr>
            <td style="padding-right: 0cm; padding-left: 0cm; background: #e6e6e6; padding-bottom: 0cm; padding-top: 0cm">
            <p style="line-height: 10.85pt; text-align: left" align="left"><span style="font-size: 7.5pt; color: black; font-family: Verdana">NodeList nl = doc.getElementsByTagName("message");</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="margin-bottom: 12pt; line-height: 14.95pt; text-align: left" align="left"><span style="font-size: 9.5pt; font-family: 宋体"><br />
</span><span style="font-size: 9.5pt; font-family: 宋体">我们通过这样一条语句所得到的是XML文档中所有&lt;message&gt;标签对应的Node对象的一个列表。然后，我们可以使用NodeList对象的item()方法来得到列表中的每一个Node对象：</span></p>
<table style="width: 435pt" cellspacing="0" cellpadding="0" width="580" border="1">
    <tbody>
        <tr>
            <td style="padding-right: 0cm; padding-left: 0cm; background: #e6e6e6; padding-bottom: 0cm; padding-top: 0cm">
            <p style="line-height: 10.85pt; text-align: left" align="left"><span style="font-size: 7.5pt; color: black; font-family: Verdana">Node my_node = nl.item(0);</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="margin-bottom: 12pt; line-height: 14.95pt; text-align: left" align="left"><span style="font-size: 9.5pt; font-family: 宋体"><br />
</span><span style="font-size: 9.5pt; font-family: 宋体">当一个Node对象被建立之后，保存在XML文档中的数据就被提取出来并封装在这个Node中了。在这个例子中，要提取Message标签内的内容，我们通常会使用Node对象的getNodeValue()方法：</span></p>
<table style="width: 435pt" cellspacing="0" cellpadding="0" width="580" border="1">
    <tbody>
        <tr>
            <td style="padding-right: 0cm; padding-left: 0cm; background: #e6e6e6; padding-bottom: 0cm; padding-top: 0cm">
            <p style="line-height: 10.85pt; text-align: left" align="left"><span style="font-size: 7.5pt; color: black; font-family: Verdana">String message = my_node.getFirstChild().getNodeValue();</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="line-height: 14.95pt; text-align: left" align="left"><span style="font-size: 9.5pt; font-family: 宋体"><br />
</span><span style="font-size: 9.5pt; font-family: 宋体">请注意，这里还使用了一个getFirstChild()方法来获得message下面的第一个子Node对象。虽然在message标签下面除了文本外并没有其它子标签或者属性，但是我们坚持在这里使用getFirseChild()方法，这主要和W3C对DOM的定义有关。W3C把标签内的文本部分也定义成一个Node，所以先要得到代表文本的那个Node，我们才能够使用getNodeValue()来获取文本的内容。 <br />
<br />
现在，既然我们已经能够从XML文件中提取出数据了，我们就可以把这些数据用在合适的地方，来构筑应用程序。 <br />
<br />
下面的内容，我们将更多的关注DOM，为DOM作一个较为详细的解析，使我们使用起来更为得心应手。 <br />
<br />
</span><strong><span style="font-size: 9.5pt; font-family: 宋体">DOM</span></strong><strong><span style="font-size: 9.5pt; font-family: 宋体">详解</span></strong></p>
<table style="background: #f7f3f7; width: 100%" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 0.75pt; padding-left: 0.75pt; padding-bottom: 0.75pt; padding-top: 0.75pt">
            <p style="text-align: left" align="left"><span style="font-size: 10pt; color: #000084; font-family: 宋体">1</span><span style="font-size: 10pt; color: #000084; font-family: 宋体">．基本的DOM对象</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="margin-bottom: 12pt; line-height: 14.95pt; text-align: left" align="left"><span style="font-size: 9.5pt; font-family: 宋体"><br />
DOM</span><span style="font-size: 9.5pt; font-family: 宋体">的基本对象有5个：Document，Node，NodeList，Element和Attr。下面就这些对象的功能和实现的方法作一个大致的介绍。</span></p>
<p style="line-height: 14.95pt; text-align: center" align="center"><span style="font-size: 9.5pt; font-family: 宋体"><br />
</span><strong><span style="font-size: 9.5pt; font-family: 宋体">点击可放大</span></strong></p>
<p style="margin-bottom: 12pt; line-height: 14.95pt; text-align: left" align="left"><span style="font-size: 9.5pt; font-family: 宋体"><br />
Document</span><span style="font-size: 9.5pt; font-family: 宋体">对象代表了整个XML的文档，所有其它的Node，都以一定的顺序包含在Document对象之内，排列成一个树形的结构，程序员可以通过遍历这颗树来得到XML文档的所有的内容，这也是对XML文档操作的起点。我们总是先通过解析XML源文件而得到一个Document对象，然后再来执行后续的操作。此外，Document还包含了创建其它节点的方法，比如createAttribut()用来创建一个Attr对象。它所包含的主要的方法有： <br />
<br />
createAttribute(String)：用给定的属性名创建一个Attr对象，并可在其后使用setAttributeNode方法来放置在某一个Element对象上面。 <br />
<br />
createElement(String)：用给定的标签名创建一个Element对象，代表XML文档中的一个标签，然后就可以在这个Element对象上添加属性或进行其它的操作。 <br />
<br />
createTextNode(String)：用给定的字符串创建一个Text对象，Text对象代表了标签或者属性中所包含的纯文本字符串。如果在一个标签内没有其它的标签，那么标签内的文本所代表的Text对象是这个Element对象的唯一子对象。 <br />
<br />
getElementsByTagName(String)：返回一个NodeList对象，它包含了所有给定标签名字的标签。 <br />
<br />
getDocumentElement()：返回一个代表这个DOM树的根节点的Element对象，也就是代表XML文档根元素的那个对象。 <br />
<br />
Node对象是DOM结构中最为基本的对象，代表了文档树中的一个抽象的节点。在实际使用的时候，很少会真正的用到Node这个对象，而是用到诸如Element、Attr、Text等Node对象的子对象来操作文档。Node对象为这些对象提供了一个抽象的、公共的根。虽然在Node对象中定义了对其子节点进行存取的方法，但是有一些Node子对象，比如Text对象，它并不存在子节点，这一点是要注意的。Node对象所包含的主要的方法有： <br />
<br />
appendChild(org.w3c.dom.Node)：为这个节点添加一个子节点，并放在所有子节点的最后，如果这个子节点已经存在，则先把它删掉再添加进去。 <br />
<br />
getFirstChild()：如果节点存在子节点，则返回第一个子节点，对等的，还有getLastChild()方法返回最后一个子节点。 <br />
<br />
getNextSibling()：返回在DOM树中这个节点的下一个兄弟节点，对等的，还有getPreviousSibling()方法返回其前一个兄弟节点。 <br />
<br />
getNodeName()：根据节点的类型返回节点的名称。 <br />
<br />
getNodeType()：返回节点的类型。 <br />
<br />
getNodeValue()：返回节点的值。 <br />
<br />
hasChildNodes()：判断是不是存在有子节点。 <br />
<br />
hasAttributes()：判断这个节点是否存在有属性。 <br />
<br />
getOwnerDocument()：返回节点所处的Document对象。 <br />
<br />
insertBefore(org.w3c.dom.Node new，org.w3c.dom.Node ref)：在给定的一个子对象前再插入一个子对象。 <br />
<br />
removeChild(org.w3c.dom.Node)：删除给定的子节点对象。 <br />
<br />
replaceChild(org.w3c.dom.Node new，org.w3c.dom.Node old)：用一个新的Node对象代替给定的子节点对象。 <br />
<br />
NodeList对象，顾名思义，就是代表了一个包含了一个或者多个Node的列表。可以简单的把它看成一个Node的数组，我们可以通过方法来获得列表中的元素： <br />
<br />
GetLength()：返回列表的长度。 <br />
<br />
Item(int)：返回指定位置的Node对象。 <br />
<br />
Element对象代表的是XML文档中的标签元素，继承于Node，亦是Node的最主要的子对象。在标签中可以包含有属性，因而Element对象中有存取其属性的方法，而任何Node中定义的方法，也可以用在Element对象上面。 <br />
<br />
getElementsByTagName(String)：返回一个NodeList对象，它包含了在这个标签中其下的子孙节点中具有给定标签名字的标签。 <br />
<br />
getTagName()：返回一个代表这个标签名字的字符串。 <br />
<br />
getAttribute(String)：返回标签中给定属性名称的属性的值。在这儿需要主要的是，应为XML文档中允许有实体属性出现，而这个方法对这些实体属性并不适用。这时候需要用到getAttributeNodes()方法来得到一个Attr对象来进行进一步的操作。 <br />
<br />
getAttributeNode(String)：返回一个代表给定属性名称的Attr对象。 <br />
<br />
Attr对象代表了某个标签中的属性。Attr继承于Node，但是因为Attr实际上是包含在Element中的，它并不能被看作是Element的子对象，因而在DOM中Attr并不是DOM树的一部分，所以Node中的getparentNode()，getpreviousSibling()和getnextSibling()返回的都将是null。也就是说，Attr其实是被看作包含它的Element对象的一部分，它并不作为DOM树中单独的一个节点出现。这一点在使用的时候要同其它的Node子对象相区别。 <br />
<br />
需要说明的是，上面所说的DOM对象在DOM中都是用接口定义的，在定义的时候使用的是与具体语言无关的IDL语言来定义的。因而，DOM其实可以在任何面向对象的语言中实现，只要它实现了DOM所定义的接口和功能就可以了。同时，有些方法在DOM中并没有定义，是用IDL的属性来表达的，当被映射到具体的语言时，这些属性被映射为相应的方法。</span></p>
<table style="background: #f7f3f7; width: 100%" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 0.75pt; padding-left: 0.75pt; padding-bottom: 0.75pt; padding-top: 0.75pt">
            <p style="text-align: left" align="left"><span style="font-size: 10pt; color: #000084; font-family: 宋体">2</span><span style="font-size: 10pt; color: #000084; font-family: 宋体">．DOM实例</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="margin-bottom: 12pt; line-height: 14.95pt; text-align: left" align="left"><span style="font-size: 9.5pt; font-family: 宋体"><br />
</span><span style="font-size: 9.5pt; font-family: 宋体">有了上面的介绍，相信你对DOM理解的更多了吧。下面的例子将让你对DOM更加熟悉起来。 <br />
<br />
先说说这个例子到底要做的是什么吧，我们希望在一个名为link.xml文件中保存了一些URL地址，通过一个简单的程序，我们可以通过DOM把这些URL读出并显示出来，也可以反过来向这个XML文件中写入加入的URL地址。很简单，却很实用，也足够来例示DOM的绝大部分用法了。 <br />
<br />
XML文件本身不复杂，就不给出它的DTD了。link.xml: </span></p>
<table style="width: 435pt" cellspacing="0" cellpadding="0" width="580" border="1">
    <tbody>
        <tr>
            <td style="padding-right: 0cm; padding-left: 0cm; background: #e6e6e6; padding-bottom: 0cm; padding-top: 0cm">
            <p style="line-height: 10.85pt; text-align: left" align="left"><span style="font-size: 7.5pt; color: black; font-family: Verdana">&lt;?xml version="1.0" standalone="yes"?&gt;<br />
            &lt;links&gt;<br />
            &lt;link&gt;<br />
            &lt;text&gt;JSP Insider&lt;/text&gt;<br />
            &lt;url newWindow="no"&gt;http://www.jspinsider.com&lt;/url&gt;<br />
            &lt;author&gt;JSP Insider&lt;/author&gt;<br />
            &lt;date&gt;<br />
            &lt;day&gt;2&lt;/day&gt;<br />
            &lt;month&gt;1&lt;/month&gt;<br />
            &lt;year&gt;2001&lt;/year&gt;<br />
            &lt;/date&gt;<br />
            &lt;description&gt;A JSP information site.&lt;/description&gt;<br />
            &lt;/link&gt;<br />
            &lt;link&gt;<br />
            &lt;text&gt;The makers of Java&lt;/text&gt;<br />
            &lt;url newWindow="no"&gt;http://java.sun.com&lt;/url&gt;<br />
            &lt;author&gt;Sun Microsystems&lt;/author&gt;<br />
            &lt;date&gt;<br />
            &lt;day&gt;3&lt;/day&gt;<br />
            &lt;month&gt;1&lt;/month&gt;<br />
            &lt;year&gt;2001&lt;/year&gt;<br />
            &lt;/date&gt;<br />
            &lt;description&gt;Sun Microsystem's website.&lt;/description&gt;<br />
            &lt;/link&gt;<br />
            &lt;link&gt;<br />
            &lt;text&gt;The standard JSP container&lt;/text&gt;<br />
            &lt;url newWindow="no"&gt;http://jakarta.apache.org&lt;/url&gt;<br />
            &lt;author&gt;Apache Group&lt;/author&gt;<br />
            &lt;date&gt;<br />
            &lt;day&gt;4&lt;/day&gt;<br />
            &lt;month&gt;1&lt;/month&gt;<br />
            &lt;year&gt;2001&lt;/year&gt;<br />
            &lt;/date&gt;<br />
            &lt;description&gt;Some great software.&lt;/description&gt;<br />
            &lt;/link&gt;<br />
            &lt;/links&gt;</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="line-height: 14.95pt; text-align: left" align="left"><span style="font-size: 9.5pt; font-family: 宋体"><br />
</span><span style="font-size: 9.5pt; font-family: 宋体">第一个程序我们称为xmldisplay.java，具体的程序清单可以在<a href="http://www.ccidnet.com/tech/code/011008/jxsource.zip">附件</a>中找到。主要的功能就是读取这个XML文件中各个节点的内容，然后在格式化输出在System.out上，我们来看看这个程序：</span></p>
<table style="width: 435pt" cellspacing="0" cellpadding="0" width="580" border="1">
    <tbody>
        <tr>
            <td style="padding-right: 0cm; padding-left: 0cm; background: #e6e6e6; padding-bottom: 0cm; padding-top: 0cm">
            <p style="line-height: 10.85pt; text-align: left" align="left"><span style="font-size: 7.5pt; color: black; font-family: Verdana">import javax.xml.parsers.*;<br />
            import org.w3c.dom.*;</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="margin-bottom: 12pt; line-height: 14.95pt; text-align: left" align="left"><span style="font-size: 9.5pt; font-family: 宋体"><br />
</span><span style="font-size: 9.5pt; font-family: 宋体">这是引入必要的类，因为在这里使用的是Sun所提供的XML解析器，因而需要引入java.xml.parsers包，其中包含了有DOM解析器和SAX解析器的具体实现。org.w3c.dom包中定义了w3c所制定的DOM接口。</span></p>
<table style="width: 435pt" cellspacing="0" cellpadding="0" width="580" border="1">
    <tbody>
        <tr>
            <td style="padding-right: 0cm; padding-left: 0cm; background: #e6e6e6; padding-bottom: 0cm; padding-top: 0cm">
            <p style="line-height: 10.85pt; text-align: left" align="left"><span style="font-size: 7.5pt; color: black; font-family: Verdana">DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();<br />
            DocumentBuilder builder=factory.newDocumentBuilder();<br />
            Document doc=builder.parse("links.xml");<br />
            doc.normalize();</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="margin-bottom: 12pt; line-height: 14.95pt; text-align: left" align="left"><span style="font-size: 9.5pt; font-family: 宋体"><br />
</span><span style="font-size: 9.5pt; font-family: 宋体">除了上面讲到的，还有一个小技巧，对Document对象调用normalize()，可以去掉XML文档中作为格式化内容的空白而映射在DOM树中的不必要的Text Node对象。否则你得到的DOM树可能并不如你所想象的那样。特别是在输出的时候，这个normalize()更为有用。</span></p>
<table style="width: 435pt" cellspacing="0" cellpadding="0" width="580" border="1">
    <tbody>
        <tr>
            <td style="padding-right: 0cm; padding-left: 0cm; background: #e6e6e6; padding-bottom: 0cm; padding-top: 0cm">
            <p style="line-height: 10.85pt; text-align: left" align="left"><span style="font-size: 7.5pt; color: black; font-family: Verdana">NodeList links =doc.getElementsByTagName("link");</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="margin-bottom: 12pt; line-height: 14.95pt; text-align: left" align="left"><span style="font-size: 9.5pt; font-family: 宋体"><br />
</span><span style="font-size: 9.5pt; font-family: 宋体">刚才说过，XML文档中的空白符也会被作为对象映射在DOM树中。因而，直接调用Node方法的getChildNodes方法有时候会有些问题，有时不能够返回所期望的NodeList对象。解决的办法是使用Element的getElementByTagName(String)，返回的NodeLise就是所期待的对象了。然后，可以用item()方法提取想要的元素。</span></p>
<table style="width: 435pt" cellspacing="0" cellpadding="0" width="580" border="1">
    <tbody>
        <tr>
            <td style="padding-right: 0cm; padding-left: 0cm; background: #e6e6e6; padding-bottom: 0cm; padding-top: 0cm">
            <p style="line-height: 10.85pt; text-align: left" align="left"><span style="font-size: 7.5pt; color: black; font-family: Verdana">for (int i=0;i&lt;links.getLength();i++){<br />
            Element link=(Element) links.item(i);<br />
            System.out.print("Content: ");<br />
            System.out.println(link.getElementsByTagName("text").item(0).getFirstChild().getNodeValue());<br />
            System.out.print("URL: ");<br />
            System.out.println(link.getElementsByTagName("url").item(0).getFirstChild().getNodeValue());<br />
            System.out.print("Author: ");<br />
            System.out.println(link.getElementsByTagName("author").item(0).getFirstChild().getNodeValue());<br />
            System.out.print("Date: ");<br />
            Element linkdate=(Element) link.getElementsByTagName("date").item(0);<br />
            String day=linkdate.getElementsByTagName("day").item(0).getFirstChild().getNodeValue();<br />
            String month=linkdate.getElementsByTagName("month").item(0).getFirstChild().getNodeValue();<br />
            String year=linkdate.getElementsByTagName("year").item(0).getFirstChild().getNodeValue();<br />
            System.out.println(day+"-"+month+"-"+year);<br />
            System.out.print("Description: ");<br />
            System.out.println(link.getElementsByTagName("description").item(0).getFirstChild().getNodeValue());<br />
            System.out.println();<br />
            }</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="margin-bottom: 12pt; line-height: 14.95pt; text-align: left" align="left"><span style="font-size: 9.5pt; font-family: 宋体"><br />
</span><span style="font-size: 9.5pt; font-family: 宋体">上面的代码片断就完成了对XML文档内容的格式化输出。只要注意到一些细节的问题，比如getFirstChile()方法和getElementsByTagName()方法的使用，这些还是比较容易的。 <br />
<br />
下面的内容，就是在修改了DOM树后重新写入到XML文档中去的问题了。这个程序名为xmlwrite.java。在JAXP1.0版本中，并没有直接的类和方法能够处理XML文档的写入问题，需要借助其它包中的一些辅助类。而在JAXP1.1版本中，引入了对XSLT的支持，所谓XSLT，就是对XML文档进行变换（Translation）后，得到一个新的文档结构。利用这个新加入的功能，我们就能够很方便的把新生成或者修改后的DOM树从新写回到XML文件中去了，下面我们来看看代码的实现，这段代码的主要功能是向links.xml文件中加入一个新的link节点：</span></p>
<table style="width: 435pt" cellspacing="0" cellpadding="0" width="580" border="1">
    <tbody>
        <tr>
            <td style="padding-right: 0cm; padding-left: 0cm; background: #e6e6e6; padding-bottom: 0cm; padding-top: 0cm">
            <p style="line-height: 10.85pt; text-align: left" align="left"><span style="font-size: 7.5pt; color: black; font-family: Verdana">import javax.xml.parsers.*;<br />
            import javax.xml.transform.*;<br />
            import javax.xml.transform.dom.DOMSource;<br />
            import javax.xml.transform.stream.StreamResult;<br />
            import org.w3c.dom.*;</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="margin-bottom: 12pt; line-height: 14.95pt; text-align: left" align="left"><span style="font-size: 9.5pt; font-family: 宋体"><br />
</span><span style="font-size: 9.5pt; font-family: 宋体">新引入的java.xml.transform包中的几个类，就是用来处理XSLT变换的。 <br />
<br />
我们希望在上面的XML文件中加入一个新的link节点，因而首先还是要读入links.xml文件，构建一个DOM树，然后再对这个DOM树进行修改（添加节点），最后把修改后的DOM写回到links.xml文件中：</span></p>
<table style="width: 435pt" cellspacing="0" cellpadding="0" width="580" border="1">
    <tbody>
        <tr>
            <td style="padding-right: 0cm; padding-left: 0cm; background: #e6e6e6; padding-bottom: 0cm; padding-top: 0cm">
            <p style="line-height: 10.85pt; text-align: left" align="left"><span style="font-size: 7.5pt; color: black; font-family: Verdana">DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();<br />
            DocumentBuilder builder=factory.newDocumentBuilder();<br />
            Document doc=builder.parse("links.xml");<br />
            doc.normalize();<br />
            //---</span><span style="font-size: 7.5pt; color: black; font-family: 宋体">取得变量</span><span style="font-size: 7.5pt; color: black; font-family: Verdana">----<br />
            String text="Hanzhong's Homepage";<br />
            String url="www.hzliu.com";<br />
            String author="Hzliu Liu";<br />
            String discription="A site from Hanzhong Liu, give u lots of suprise!!!";</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="margin-bottom: 12pt; line-height: 14.95pt; text-align: left" align="left"><span style="font-size: 9.5pt; font-family: 宋体"><br />
</span><span style="font-size: 9.5pt; font-family: 宋体">为了看清重点，简化程序，我们把要加入的内容硬编码到记忆String对象中，而实际操作中，往往利用一个界面来提取用户输入，或者通过JDBC从数据库中提取想要的内容。</span></p>
<table style="width: 435pt" cellspacing="0" cellpadding="0" width="580" border="1">
    <tbody>
        <tr>
            <td style="padding-right: 0cm; padding-left: 0cm; background: #e6e6e6; padding-bottom: 0cm; padding-top: 0cm">
            <p style="line-height: 10.85pt; text-align: left" align="left"><span style="font-size: 7.5pt; color: black; font-family: Verdana">Text textseg;<br />
            Element link=doc.createElement("link");</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="margin-bottom: 12pt; line-height: 14.95pt; text-align: left" align="left"><span style="font-size: 9.5pt; font-family: 宋体"><br />
</span><span style="font-size: 9.5pt; font-family: 宋体">首先应该明了的是，无论什么类型的Node，Text型的也好，Attr型的也好，Element型的也好，它们的创建都是通过Document对象中的createXXX()方法来创建的（XXX代表具体要创建的类型），因此，我们要向XML文档中添加一个link项目，首先要创建一个link对象：</span></p>
<table style="width: 435pt" cellspacing="0" cellpadding="0" width="580" border="1">
    <tbody>
        <tr>
            <td style="padding-right: 0cm; padding-left: 0cm; background: #e6e6e6; padding-bottom: 0cm; padding-top: 0cm">
            <p style="line-height: 10.85pt; text-align: left" align="left"><span style="font-size: 7.5pt; color: black; font-family: Verdana">Element linktext=doc.createElement("text");<br />
            textseg=doc.createTextNode(text);<br />
            linktext.appendChild(textseg);<br />
            link.appendChild(linktext);<br />
            Element linkurl=doc.createElement("url");<br />
            textseg=doc.createTextNode(url);<br />
            linkurl.appendChild(textseg);<br />
            link.appendChild(linkurl);<br />
            Element linkauthor=doc.createElement("author");<br />
            textseg=doc.createTextNode(author);<br />
            linkauthor.appendChild(textseg);<br />
            link.appendChild(linkauthor);<br />
            java.util.Calendar rightNow = java.util.Calendar.getInstance();<br />
            String day=Integer.toString(rightNow.get(java.util.Calendar.DAY_OF_MONTH));<br />
            String month=Integer.toString(rightNow.get(java.util.Calendar.MONTH));<br />
            String year=Integer.toString(rightNow.get(java.util.Calendar.YEAR));<br />
            Element linkdate=doc.createElement("date");<br />
            Element linkdateday=doc.createElement("day");<br />
            textseg=doc.createTextNode(day);<br />
            linkdateday.appendChild(textseg);<br />
            Element linkdatemonth=doc.createElement("month");<br />
            textseg=doc.createTextNode(month);<br />
            linkdatemonth.appendChild(textseg);<br />
            Element linkdateyear=doc.createElement("year");<br />
            textseg=doc.createTextNode(year);<br />
            linkdateyear.appendChild(textseg);<br />
            linkdate.appendChild(linkdateday);<br />
            linkdate.appendChild(linkdatemonth);<br />
            linkdate.appendChild(linkdateyear);<br />
            link.appendChild(linkdate);<br />
            Element linkdiscription=doc.createElement("description");<br />
            textseg=doc.createTextNode(discription);<br />
            linkdiscription.appendChild(textseg);<br />
            link.appendChild(linkdiscription);</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="margin-bottom: 12pt; line-height: 14.95pt; text-align: left" align="left"><span style="font-size: 9.5pt; font-family: 宋体"><br />
</span><span style="font-size: 9.5pt; font-family: 宋体">创建节点的过程可能有些千篇一律，但需要注意的地方是，对Element中所包含的text（在DOM中，这些text也是代表了一个Node的，因此也必须为它们创建相应的node），不能直接用Element对象的setNodeValue()方法来设置这些text的内容，而需要用创建的Text对象的setNodeValue()方法来设置文本，这样才能够把创建的Element和其文本内容添加到DOM树中。看看前面的代码，你会更好的理解这一点：</span></p>
<table style="width: 435pt" cellspacing="0" cellpadding="0" width="580" border="1">
    <tbody>
        <tr>
            <td style="padding-right: 0cm; padding-left: 0cm; background: #e6e6e6; padding-bottom: 0cm; padding-top: 0cm">
            <p style="line-height: 10.85pt; text-align: left" align="left"><span style="font-size: 7.5pt; color: black; font-family: Verdana">doc.getDocumentElement().appendChild(link);</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="margin-bottom: 12pt; line-height: 14.95pt; text-align: left" align="left"><span style="font-size: 9.5pt; font-family: 宋体"><br />
</span><span style="font-size: 9.5pt; font-family: 宋体">最后，不要忘记把创建好的节点添加到DOM树中。Document类的getDocumentElement()方法，返回代表文档根节点的Element对象。在XML文档中，根节点一定是唯一的。</span></p>
<table style="width: 435pt" cellspacing="0" cellpadding="0" width="580" border="1">
    <tbody>
        <tr>
            <td style="padding-right: 0cm; padding-left: 0cm; background: #e6e6e6; padding-bottom: 0cm; padding-top: 0cm">
            <p style="line-height: 10.85pt; text-align: left" align="left"><span style="font-size: 7.5pt; color: black; font-family: Verdana">TransformerFactory tFactory =TransformerFactory.newInstance();<br />
            Transformer transformer = tFactory.newTransformer();<br />
            DOMSource source = new DOMSource(doc);<br />
            StreamResult result = new StreamResult(new java.io.File("links.xml"));<br />
            transformer.transform(source, result);</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-size: 9.5pt; font-family: 宋体"><br />
</span><span style="font-size: 9.5pt; font-family: 宋体">然后就是用XSLT把DOM树输出了。这里的TransformerFactory也同样应用了工厂模式，使得具体的代码同具体的变换器无关。实现的方法和DocumentBuilderFactory相同，这儿就不赘述了。Transformer类的transfrom方法接受两个参数、一个数据源Source和一个输出目标Result。这里分别使用的是DOMSource和StreamResult，这样就能够把DOM的内容输出到一个输出流中，当这个输出流是一个文件的时候，DOM的内容就被写入到文件中去了。</span></p>
<br />
<img src ="http://www.blogjava.net/lizhuxin/aggbug/221937.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lizhuxin/" target="_blank">☆</a> 2008-08-14 12:15 <a href="http://www.blogjava.net/lizhuxin/articles/221937.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java解析XML基础知识问答</title><link>http://www.blogjava.net/lizhuxin/articles/221800.html</link><dc:creator>☆</dc:creator><author>☆</author><pubDate>Wed, 13 Aug 2008 10:47:00 GMT</pubDate><guid>http://www.blogjava.net/lizhuxin/articles/221800.html</guid><wfw:comment>http://www.blogjava.net/lizhuxin/comments/221800.html</wfw:comment><comments>http://www.blogjava.net/lizhuxin/articles/221800.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lizhuxin/comments/commentRss/221800.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lizhuxin/services/trackbacks/221800.html</trackback:ping><description><![CDATA[<p>java解析XML基础知识问答：<br />
<br />
1、xml有哪些解析技术?区别是什么?<br />
答：有DOM,SAX等<br />
　　DOM:处理大型文件时其性能下降的非常厉害。这个问题是由DOM的树结构所造成的，这种结构占用的内存较多，<br />
&nbsp;&nbsp; 而且DOM必须在解析文件之前把整个文档装入内存,适合对XML的随机访问<br />
&nbsp;&nbsp; SAX:不现于DOM,SAX是事件驱动型的XML解析方式。它顺序读取XML文件，不需要一次全部装载整个文件。<br />
&nbsp;&nbsp; 当遇到像文件开头，文档结束，或者标签开头与标签结束时，它会触发一个事件，<br />
&nbsp;&nbsp; 用户通过在其回调事件中写入处理代码来处理XML文件，适合对XML的顺序访问</p>
<p>2、你在项目中用到了xml技术的哪些方面?如何实现的?<br />
　　答：用到了数据存贮，信息配置两方面。在做数据交换平台时，将不同数据源的数据组装成XML文件，<br />
&nbsp;&nbsp;&nbsp; 然后将XML文件压缩打包加密后通过网络传送给接收者，接收解密与解压缩后再同XML文件中还原相关信息进行处理。<br />
&nbsp;&nbsp;&nbsp; 在做软件配置时，利用XML可以很方便的进行，软件的各种配置参数都存贮在XML文件中。</p>
<p>&nbsp;</p>
<img src ="http://www.blogjava.net/lizhuxin/aggbug/221800.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lizhuxin/" target="_blank">☆</a> 2008-08-13 18:47 <a href="http://www.blogjava.net/lizhuxin/articles/221800.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>