您的位置:首页 > 编程语言 > Java开发

Java的XML文件操作之DOM入门篇 (3)

2010-01-18 22:45 417 查看
2.DOM实例

有了上面的介绍,相信你对DOM理解的更多了吧。下面的例子将让你对DOM更加熟悉起来。

先说说这个例子到底要做的是什么吧,我们希望在一个名为link.xml文件中保存了一些URL地址,通过一个简单的程序,我们可以通过DOM把这些URL读出并显示出来,也可以反过来向这个XML文件中写入加入的URL地址。很简单,却很实用,也足够来例示DOM的绝大部分用法了。

XML文件本身不复杂,就不给出它的DTD了。link.xml:

JSP Insider
http://www.jspinsider.com
JSP Insider

2

1

2001

A JSP information site.

The makers of Java
http://java.sun.com
Sun Microsystems

3

1

2001

Sun Microsystem's website.

The standard JSP container
http://jakarta.apache.org
Apache Group

4

1

2001

Some great software.

第一个程序我们称为xmldisplay.java,具体的程序清单可以在附件中找到。主要的功能就是读取这个XML文件中各个节点的内容,然后在格式化输出在System.out上,我们来看看这个程序:

import javax.xml.parsers.*;

import org.w3c.dom.*;

这是引入必要的类,因为在这里使用的是Sun所提供的XML解析器,因而需要引入java.xml.parsers包,其中包含了有DOM解析器和SAX解析器的具体实现。org.w3c.dom包中定义了w3c所制定的DOM接口。

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

DocumentBuilder builder=factory.newDocumentBuilder();

Document doc=builder.parse("links.xml");

doc.normalize();

除了上面讲到的,还有一个小技巧,对Document对象调用normalize(),可以去掉XML文档中作为格式化内容的空白而映射在DOM树中的不必要的Text Node对象。否则你得到的DOM树可能并不如你所想象的那样。特别是在输出的时候,这个normalize()更为有用。

NodeList links =doc.getElementsByTagName("link");

刚才说过,XML文档中的空白符也会被作为对象映射在DOM树中。因而,直接调用Node方法的getChildNodes方法有时候会有些问题,有时不能够返回所期望的NodeList对象。解决的办法是使用Element的getElementByTagName(String),返回的NodeLise就是所期待的对象了。然后,可以用item()方法提取想要的元素。

for (int i=0;i
Element link=(Element) links.item(i);

System.out.print("Content: ");

System.out.println(link.getElementsByTagName("text").item(0).getFirstChild().getNodeValue());

System.out.print("URL: ");

System.out.println(link.getElementsByTagName("url").item(0).getFirstChild().getNodeValue());

System.out.print("Author: ");

System.out.println(link.getElementsByTagName("author").item(0).getFirstChild().getNodeValue());

System.out.print("Date: ");

Element linkdate=(Element) link.getElementsByTagName("date").item(0);

String day=linkdate.getElementsByTagName("day").item(0).getFirstChild().getNodeValue();

String month=linkdate.getElementsByTagName("month").item(0).getFirstChild().getNodeValue();

String year=linkdate.getElementsByTagName("year").item(0).getFirstChild().getNodeValue();

System.out.println(day+"-"+month+"-"+year);

System.out.print("Description: ");

System.out.println(link.getElementsByTagName("description").item(0).getFirstChild().getNodeValue());

System.out.println();

}

上面的代码片断就完成了对XML文档内容的格式化输出。只要注意到一些细节的问题,比如getFirstChile()方法和getElementsByTagName()方法的使用,这些还是比较容易的。

下面的内容,就是在修改了DOM树后重新写入到XML文档中去的问题了。这个程序名为xmlwrite.java。在JAXP1.0版本中,并没有直接的类和方法能够处理XML文档的写入问题,需要借助其它包中的一些辅助类。而在JAXP1.1版本中,引入了对XSLT的支持,所谓XSLT,就是对XML文档进行变换(Translation)后,得到一个新的文档结构。利用这个新加入的功能,我们就能够很方便的把新生成或者修改后的DOM树从新写回到XML文件中去了,下面我们来看看代码的实现,这段代码的主要功能是向links.xml文件中加入一个新的link节点:

import javax.xml.parsers.*;

import javax.xml.transform.*;

import javax.xml.transform.dom.DOMSource;

import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.*;

新引入的java.xml.transform包中的几个类,就是用来处理XSLT变换的。

我们希望在上面的XML文件中加入一个新的link节点,因而首先还是要读入links.xml文件,构建一个DOM树,然后再对这个DOM树进行修改(添加节点),最后把修改后的DOM写回到links.xml文件中:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

DocumentBuilder builder=factory.newDocumentBuilder();

Document doc=builder.parse("links.xml");

doc.normalize();

//---取得变量----

String text="Hanzhong's Homepage";

String url="www.hzliu.com";

String author="Hzliu Liu";

String discription="A site from Hanzhong Liu, give u lots of suprise!!!";

为了看清重点,简化程序,我们把要加入的内容硬编码到记忆String对象中,而实际操作中,往往利用一个界面来提取用户输入,或者通过JDBC从数据库中提取想要的内容。

Text textseg;

Element link=doc.createElement("link");

首先应该明了的是,无论什么类型的Node,Text型的也好,Attr型的也好,Element型的也好,它们的创建都是通过Document对象中的createXXX()方法来创建的(XXX代表具体要创建的类型),因此,我们要向XML文档中添加一个link项目,首先要创建一个link对象:

Element linktext=doc.createElement("text");

textseg=doc.createTextNode(text);

linktext.appendChild(textseg);

link.appendChild(linktext);

Element linkurl=doc.createElement("url");

textseg=doc.createTextNode(url);

linkurl.appendChild(textseg);

link.appendChild(linkurl);

Element linkauthor=doc.createElement("author");

textseg=doc.createTextNode(author);

linkauthor.appendChild(textseg);

link.appendChild(linkauthor);

java.util.Calendar rightNow = java.util.Calendar.getInstance();

String day=Integer.toString(rightNow.get(java.util.Calendar.DAY_OF_MONTH));

String month=Integer.toString(rightNow.get(java.util.Calendar.MONTH));

String year=Integer.toString(rightNow.get(java.util.Calendar.YEAR));

Element linkdate=doc.createElement("date");

Element linkdateday=doc.createElement("day");

textseg=doc.createTextNode(day);

linkdateday.appendChild(textseg);

Element linkdatemonth=doc.createElement("month");

textseg=doc.createTextNode(month);

linkdatemonth.appendChild(textseg);

Element linkdateyear=doc.createElement("year");

textseg=doc.createTextNode(year);

linkdateyear.appendChild(textseg);

linkdate.appendChild(linkdateday);

linkdate.appendChild(linkdatemonth);

linkdate.appendChild(linkdateyear);

link.appendChild(linkdate);

Element linkdiscription=doc.createElement("description");

textseg=doc.createTextNode(discription);

linkdiscription.appendChild(textseg);

link.appendChild(linkdiscription);

创建节点的过程可能有些千篇一律,但需要注意的地方是,对Element中所包含的text(在DOM中,这些text也是代表了一个Node的,因此也必须为它们创建相应的node),不能直接用Element对象的setNodeValue()方法来设置这些text的内容,而需要用创建的Text对象的setNodeValue()方法来设置文本,这样才能够把创建的Element和其文本内容添加到DOM树中。看看前面的代码,你会更好的理解这一点:

doc.getDocumentElement().appendChild(link);

最后,不要忘记把创建好的节点添加到DOM树中。Document类的getDocumentElement()方法,返回代表文档根节点的Element对象。在XML文档中,根节点一定是唯一的。

TransformerFactory tFactory =TransformerFactory.newInstance();

Transformer transformer = tFactory.newTransformer();

DOMSource source = new DOMSource(doc);

StreamResult result = new StreamResult(new java.io.File("links.xml"));

transformer.transform(source, result);

然后就是用XSLT把DOM树输出了。这里的TransformerFactory也同样应用了工厂模式,使得具体的代码同具体的变换器无关。实现的方法和DocumentBuilderFactory相同,这儿就不赘述了。Transformer类的transfrom方法接受两个参数、一个数据源Source和一个输出目标Result。这里分别使用的是DOMSource和StreamResult,这样就能够把DOM的内容输出到一个输出流中,当这个输出流是一个文件的时候,DOM的内容就被写入到文件中去了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息