- 浏览: 602791 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
limeng650419:
想要将一个项目类生成在同一个类图怎么办》?
PowerDesigner导入java类生成类图 -
q77102902:
一语道破天机啊!
Weblogic 数据源及连接池配置问题Warning! Connectivity to backend database not verified -
chaliszhou:
收藏下,!!!
JAVA读写文件,如何避免中文乱码 -
lal324:
同上 顶起来
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/di -
luchuan10000:
非常正确!!!
JAVA读写文件,如何避免中文乱码
一开始做XML解析,老大给介绍的这篇帖子,很不错的说
DOM初步
DOM是Document Object Model的缩写,即文档对象模型。前面说过,XML将数据组织为一颗树,所以DOM就是对这颗树的一个对象描叙。通俗的说,就是通过解析XML文档,为XML文档在逻辑上建立一个树模型,树的节点是一个个对象。我们通过存取这些对象就能够存取XML文档的内容。
下面我们来看一个简单的例子,看看在DOM中,我们是如何来操作一个XML文档的。
这是一个XML文档,也是我们要操作的对象:
<?xml version="1.0" encoding="UTF-8"?>
<messages>
<message>Good-bye serialization, hello Java!</message>
</messages>
下面,我们需要把这个文档的内容解析到一个个的Java对象中去供程序使用,利用JAXP,我们只需几行代码就能做到这一点。首先,我们需要建立一个解析器工厂,以利用这个工厂来获得一个具体的解析器对象:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
我们在这里使用DocumentBuilderFacotry的目的是为了创建与具体解析器无关的程序,当DocumentBuilderFactory类的静态方法newInstance()被调用时,它根据一个系统变量来决定具体使用哪一个解析器。又因为所有的解析器都服从于JAXP所定义的接口,所以无论具体使用哪一个解析器,代码都是一样的。所以当在不同的解析器之间进行切换时,只需要更改系统变量的值,而不用更改任何代码。这就是工厂所带来的好处。这个工厂模式的具体实现,可以参看下面的类图。
DocumentBuilder db = dbf.newDocumentBuilder();
当获得一个工厂对象后,使用它的静态方法newDocumentBuilder()方法可以获得一个DocumentBuilder对象,这个对象代表了具体的DOM解析器。但具体是哪一种解析器,微软的或者IBM的,对于程序而言并不重要。
然后,我们就可以利用这个解析器来对XML文档进行解析了:
Document doc = db.parse("c:/xml/message.xml");
DocumentBuilder的parse()方法接受一个XML文档名作为输入参数,返回一个Document对象,这个Document对象就代表了一个XML文档的树模型。以后所有的对XML文档的操作,都与解析器无关,直接在这个Document对象上进行操作就可以了。而具体对Document操作的方法,就是由DOM所定义的了。
点击可放大
Jaxp支持W3C所推荐的DOM 2。如果你对DOM很熟悉,那么下面的内容就很简单了:只需要按照DOM的规范来进行方法调用就可以。当然,如果你对DOM不清楚,也不用着急,后面我们会有详细的介绍。在这儿,你所要知道并牢记的是:DOM是用来描叙XML文档中的数据的模型,引入DOM的全部原因就是为了用这个模型来操作XML文档的中的数据。DOM规范中定义有节点(即对象)、属性和方法,我们通过这些节点的存取来存取XML的数据。
从上面得到的Document对象开始,我们就可以开始我们的DOM之旅了。使用Document对象的getElementsByTagName()方法,我们可以得到一个NodeList对象,一个Node对象代表了一个XML文档中的一个标签元素,而NodeList对象,观其名而知其意,所代表的是一个Node对象的列表:
NodeList nl = doc.getElementsByTagName("message");
我们通过这样一条语句所得到的是XML文档中所有<message>标签对应的Node对象的一个列表。然后,我们可以使用NodeList对象的item()方法来得到列表中的每一个Node对象:
Node my_node = nl.item(0);
当一个Node对象被建立之后,保存在XML文档中的数据就被提取出来并封装在这个Node中了。在这个例子中,要提取Message标签内的内容,我们通常会使用Node对象的getNodeValue()方法:
String message = my_node.getFirstChild().getNodeValue();
请注意,这里还使用了一个getFirstChild()方法来获得message下面的第一个子Node对象。虽然在message标签下面除了文本外并没有其它子标签或者属性,但是我们坚持在这里使用getFirseChild()方法,这主要和W3C对DOM的定义有关。W3C把标签内的文本部分也定义成一个Node,所以先要得到代表文本的那个Node,我们才能够使用getNodeValue()来获取文本的内容。
现在,既然我们已经能够从XML文件中提取出数据了,我们就可以把这些数据用在合适的地方,来构筑应用程序。
下面的内容,我们将更多的关注DOM,为DOM作一个较为详细的解析,使我们使用起来更为得心应手。
DOM详解
1.基本的DOM对象
DOM的基本对象有5个:Document,Node,NodeList,Element和Attr。下面就这些对象的功能和实现的方法作一个大致的介绍。
点击可放大
Document对象代表了整个XML的文档,所有其它的Node,都以一定的顺序包含在Document对象之内,排列成一个树形的结构,程序员可以通过遍历这颗树来得到XML文档的所有的内容,这也是对XML文档操作的起点。我们总是先通过解析XML源文件而得到一个Document对象,然后再来执行后续的操作。此外,Document还包含了创建其它节点的方法,比如createAttribut()用来创建一个Attr对象。它所包含的主要的方法有:
createAttribute(String):用给定的属性名创建一个Attr对象,并可在其后使用setAttributeNode方法来放置在某一个Element对象上面。
createElement(String):用给定的标签名创建一个Element对象,代表XML文档中的一个标签,然后就可以在这个Element对象上添加属性或进行其它的操作。
createTextNode(String):用给定的字符串创建一个Text对象,Text对象代表了标签或者属性中所包含的纯文本字符串。如果在一个标签内没有其它的标签,那么标签内的文本所代表的Text对象是这个Element对象的唯一子对象。
getElementsByTagName(String):返回一个NodeList对象,它包含了所有给定标签名字的标签。
getDocumentElement():返回一个代表这个DOM树的根节点的Element对象,也就是代表XML文档根元素的那个对象。
Node对象是DOM结构中最为基本的对象,代表了文档树中的一个抽象的节点。在实际使用的时候,很少会真正的用到Node这个对象,而是用到诸如Element、Attr、Text等Node对象的子对象来操作文档。Node对象为这些对象提供了一个抽象的、公共的根。虽然在Node对象中定义了对其子节点进行存取的方法,但是有一些Node子对象,比如Text对象,它并不存在子节点,这一点是要注意的。Node对象所包含的主要的方法有:
appendChild(org.w3c.dom.Node):为这个节点添加一个子节点,并放在所有子节点的最后,如果这个子节点已经存在,则先把它删掉再添加进去。
getFirstChild():如果节点存在子节点,则返回第一个子节点,对等的,还有getLastChild()方法返回最后一个子节点。
getNextSibling():返回在DOM树中这个节点的下一个兄弟节点,对等的,还有getPreviousSibling()方法返回其前一个兄弟节点。
getNodeName():根据节点的类型返回节点的名称。
getNodeType():返回节点的类型。
getNodeValue():返回节点的值。
hasChildNodes():判断是不是存在有子节点。
hasAttributes():判断这个节点是否存在有属性。
getOwnerDocument():返回节点所处的Document对象。
insertBefore(org.w3c.dom.Node new,org.w3c.dom.Node ref):在给定的一个子对象前再插入一个子对象。
removeChild(org.w3c.dom.Node):删除给定的子节点对象。
replaceChild(org.w3c.dom.Node new,org.w3c.dom.Node old):用一个新的Node对象代替给定的子节点对象。
NodeList对象,顾名思义,就是代表了一个包含了一个或者多个Node的列表。可以简单的把它看成一个Node的数组,我们可以通过方法来获得列表中的元素:
GetLength():返回列表的长度。
Item(int):返回指定位置的Node对象。
Element对象代表的是XML文档中的标签元素,继承于Node,亦是Node的最主要的子对象。在标签中可以包含有属性,因而Element对象中有存取其属性的方法,而任何Node中定义的方法,也可以用在Element对象上面。
getElementsByTagName(String):返回一个NodeList对象,它包含了在这个标签中其下的子孙节点中具有给定标签名字的标签。
getTagName():返回一个代表这个标签名字的字符串。
getAttribute(String):返回标签中给定属性名称的属性的值。在这儿需要主要的是,应为XML文档中允许有实体属性出现,而这个方法对这些实体属性并不适用。这时候需要用到getAttributeNodes()方法来得到一个Attr对象来进行进一步的操作。
getAttributeNode(String):返回一个代表给定属性名称的Attr对象。
Attr对象代表了某个标签中的属性。Attr继承于Node,但是因为Attr实际上是包含在Element中的,它并不能被看作是Element的子对象,因而在DOM中Attr并不是DOM树的一部分,所以Node中的getparentNode(),getpreviousSibling()和getnextSibling()返回的都将是null。也就是说,Attr其实是被看作包含它的Element对象的一部分,它并不作为DOM树中单独的一个节点出现。这一点在使用的时候要同其它的Node子对象相区别。
需要说明的是,上面所说的DOM对象在DOM中都是用接口定义的,在定义的时候使用的是与具体语言无关的IDL语言来定义的。因而,DOM其实可以在任何面向对象的语言中实现,只要它实现了DOM所定义的接口和功能就可以了。同时,有些方法在DOM中并没有定义,是用IDL的属性来表达的,当被映射到具体的语言时,这些属性被映射为相应的方法。
2.DOM实例
有了上面的介绍,相信你对DOM理解的更多了吧。下面的例子将让你对DOM更加熟悉起来。
先说说这个例子到底要做的是什么吧,我们希望在一个名为link.xml文件中保存了一些URL地址,通过一个简单的程序,我们可以通过DOM把这些URL读出并显示出来,也可以反过来向这个XML文件中写入加入的URL地址。很简单,却很实用,也足够来例示DOM的绝大部分用法了。
XML文件本身不复杂,就不给出它的DTD了。link.xml:
<?xml version="1.0" standalone="yes"?>
<links>
<link>
<text>JSP Insider</text>
<url newWindow="no">http://www.jspinsider.com</url>
<author>JSP Insider</author>
<date>
<day>2</day>
<month>1</month>
<year>2001</year>
</date>
<description>A JSP information site.</description>
</link>
<link>
<text>The makers of Java</text>
<url newWindow="no">http://java.sun.com</url>
<author>Sun Microsystems</author>
<date>
<day>3</day>
<month>1</month>
<year>2001</year>
</date>
<description>Sun Microsystem's website.</description>
</link>
<link>
<text>The standard JSP container</text>
<url newWindow="no">http://jakarta.apache.org</url>
<author>Apache Group</author>
<date>
<day>4</day>
<month>1</month>
<year>2001</year>
</date>
<description>Some great software.</description>
</link>
</links>
第一个程序我们称为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<links.getLength();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的内容就被写入到文件中去了。
DOM初步
DOM是Document Object Model的缩写,即文档对象模型。前面说过,XML将数据组织为一颗树,所以DOM就是对这颗树的一个对象描叙。通俗的说,就是通过解析XML文档,为XML文档在逻辑上建立一个树模型,树的节点是一个个对象。我们通过存取这些对象就能够存取XML文档的内容。
下面我们来看一个简单的例子,看看在DOM中,我们是如何来操作一个XML文档的。
这是一个XML文档,也是我们要操作的对象:
<?xml version="1.0" encoding="UTF-8"?>
<messages>
<message>Good-bye serialization, hello Java!</message>
</messages>
下面,我们需要把这个文档的内容解析到一个个的Java对象中去供程序使用,利用JAXP,我们只需几行代码就能做到这一点。首先,我们需要建立一个解析器工厂,以利用这个工厂来获得一个具体的解析器对象:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
我们在这里使用DocumentBuilderFacotry的目的是为了创建与具体解析器无关的程序,当DocumentBuilderFactory类的静态方法newInstance()被调用时,它根据一个系统变量来决定具体使用哪一个解析器。又因为所有的解析器都服从于JAXP所定义的接口,所以无论具体使用哪一个解析器,代码都是一样的。所以当在不同的解析器之间进行切换时,只需要更改系统变量的值,而不用更改任何代码。这就是工厂所带来的好处。这个工厂模式的具体实现,可以参看下面的类图。
DocumentBuilder db = dbf.newDocumentBuilder();
当获得一个工厂对象后,使用它的静态方法newDocumentBuilder()方法可以获得一个DocumentBuilder对象,这个对象代表了具体的DOM解析器。但具体是哪一种解析器,微软的或者IBM的,对于程序而言并不重要。
然后,我们就可以利用这个解析器来对XML文档进行解析了:
Document doc = db.parse("c:/xml/message.xml");
DocumentBuilder的parse()方法接受一个XML文档名作为输入参数,返回一个Document对象,这个Document对象就代表了一个XML文档的树模型。以后所有的对XML文档的操作,都与解析器无关,直接在这个Document对象上进行操作就可以了。而具体对Document操作的方法,就是由DOM所定义的了。
点击可放大
Jaxp支持W3C所推荐的DOM 2。如果你对DOM很熟悉,那么下面的内容就很简单了:只需要按照DOM的规范来进行方法调用就可以。当然,如果你对DOM不清楚,也不用着急,后面我们会有详细的介绍。在这儿,你所要知道并牢记的是:DOM是用来描叙XML文档中的数据的模型,引入DOM的全部原因就是为了用这个模型来操作XML文档的中的数据。DOM规范中定义有节点(即对象)、属性和方法,我们通过这些节点的存取来存取XML的数据。
从上面得到的Document对象开始,我们就可以开始我们的DOM之旅了。使用Document对象的getElementsByTagName()方法,我们可以得到一个NodeList对象,一个Node对象代表了一个XML文档中的一个标签元素,而NodeList对象,观其名而知其意,所代表的是一个Node对象的列表:
NodeList nl = doc.getElementsByTagName("message");
我们通过这样一条语句所得到的是XML文档中所有<message>标签对应的Node对象的一个列表。然后,我们可以使用NodeList对象的item()方法来得到列表中的每一个Node对象:
Node my_node = nl.item(0);
当一个Node对象被建立之后,保存在XML文档中的数据就被提取出来并封装在这个Node中了。在这个例子中,要提取Message标签内的内容,我们通常会使用Node对象的getNodeValue()方法:
String message = my_node.getFirstChild().getNodeValue();
请注意,这里还使用了一个getFirstChild()方法来获得message下面的第一个子Node对象。虽然在message标签下面除了文本外并没有其它子标签或者属性,但是我们坚持在这里使用getFirseChild()方法,这主要和W3C对DOM的定义有关。W3C把标签内的文本部分也定义成一个Node,所以先要得到代表文本的那个Node,我们才能够使用getNodeValue()来获取文本的内容。
现在,既然我们已经能够从XML文件中提取出数据了,我们就可以把这些数据用在合适的地方,来构筑应用程序。
下面的内容,我们将更多的关注DOM,为DOM作一个较为详细的解析,使我们使用起来更为得心应手。
DOM详解
1.基本的DOM对象
DOM的基本对象有5个:Document,Node,NodeList,Element和Attr。下面就这些对象的功能和实现的方法作一个大致的介绍。
点击可放大
Document对象代表了整个XML的文档,所有其它的Node,都以一定的顺序包含在Document对象之内,排列成一个树形的结构,程序员可以通过遍历这颗树来得到XML文档的所有的内容,这也是对XML文档操作的起点。我们总是先通过解析XML源文件而得到一个Document对象,然后再来执行后续的操作。此外,Document还包含了创建其它节点的方法,比如createAttribut()用来创建一个Attr对象。它所包含的主要的方法有:
createAttribute(String):用给定的属性名创建一个Attr对象,并可在其后使用setAttributeNode方法来放置在某一个Element对象上面。
createElement(String):用给定的标签名创建一个Element对象,代表XML文档中的一个标签,然后就可以在这个Element对象上添加属性或进行其它的操作。
createTextNode(String):用给定的字符串创建一个Text对象,Text对象代表了标签或者属性中所包含的纯文本字符串。如果在一个标签内没有其它的标签,那么标签内的文本所代表的Text对象是这个Element对象的唯一子对象。
getElementsByTagName(String):返回一个NodeList对象,它包含了所有给定标签名字的标签。
getDocumentElement():返回一个代表这个DOM树的根节点的Element对象,也就是代表XML文档根元素的那个对象。
Node对象是DOM结构中最为基本的对象,代表了文档树中的一个抽象的节点。在实际使用的时候,很少会真正的用到Node这个对象,而是用到诸如Element、Attr、Text等Node对象的子对象来操作文档。Node对象为这些对象提供了一个抽象的、公共的根。虽然在Node对象中定义了对其子节点进行存取的方法,但是有一些Node子对象,比如Text对象,它并不存在子节点,这一点是要注意的。Node对象所包含的主要的方法有:
appendChild(org.w3c.dom.Node):为这个节点添加一个子节点,并放在所有子节点的最后,如果这个子节点已经存在,则先把它删掉再添加进去。
getFirstChild():如果节点存在子节点,则返回第一个子节点,对等的,还有getLastChild()方法返回最后一个子节点。
getNextSibling():返回在DOM树中这个节点的下一个兄弟节点,对等的,还有getPreviousSibling()方法返回其前一个兄弟节点。
getNodeName():根据节点的类型返回节点的名称。
getNodeType():返回节点的类型。
getNodeValue():返回节点的值。
hasChildNodes():判断是不是存在有子节点。
hasAttributes():判断这个节点是否存在有属性。
getOwnerDocument():返回节点所处的Document对象。
insertBefore(org.w3c.dom.Node new,org.w3c.dom.Node ref):在给定的一个子对象前再插入一个子对象。
removeChild(org.w3c.dom.Node):删除给定的子节点对象。
replaceChild(org.w3c.dom.Node new,org.w3c.dom.Node old):用一个新的Node对象代替给定的子节点对象。
NodeList对象,顾名思义,就是代表了一个包含了一个或者多个Node的列表。可以简单的把它看成一个Node的数组,我们可以通过方法来获得列表中的元素:
GetLength():返回列表的长度。
Item(int):返回指定位置的Node对象。
Element对象代表的是XML文档中的标签元素,继承于Node,亦是Node的最主要的子对象。在标签中可以包含有属性,因而Element对象中有存取其属性的方法,而任何Node中定义的方法,也可以用在Element对象上面。
getElementsByTagName(String):返回一个NodeList对象,它包含了在这个标签中其下的子孙节点中具有给定标签名字的标签。
getTagName():返回一个代表这个标签名字的字符串。
getAttribute(String):返回标签中给定属性名称的属性的值。在这儿需要主要的是,应为XML文档中允许有实体属性出现,而这个方法对这些实体属性并不适用。这时候需要用到getAttributeNodes()方法来得到一个Attr对象来进行进一步的操作。
getAttributeNode(String):返回一个代表给定属性名称的Attr对象。
Attr对象代表了某个标签中的属性。Attr继承于Node,但是因为Attr实际上是包含在Element中的,它并不能被看作是Element的子对象,因而在DOM中Attr并不是DOM树的一部分,所以Node中的getparentNode(),getpreviousSibling()和getnextSibling()返回的都将是null。也就是说,Attr其实是被看作包含它的Element对象的一部分,它并不作为DOM树中单独的一个节点出现。这一点在使用的时候要同其它的Node子对象相区别。
需要说明的是,上面所说的DOM对象在DOM中都是用接口定义的,在定义的时候使用的是与具体语言无关的IDL语言来定义的。因而,DOM其实可以在任何面向对象的语言中实现,只要它实现了DOM所定义的接口和功能就可以了。同时,有些方法在DOM中并没有定义,是用IDL的属性来表达的,当被映射到具体的语言时,这些属性被映射为相应的方法。
2.DOM实例
有了上面的介绍,相信你对DOM理解的更多了吧。下面的例子将让你对DOM更加熟悉起来。
先说说这个例子到底要做的是什么吧,我们希望在一个名为link.xml文件中保存了一些URL地址,通过一个简单的程序,我们可以通过DOM把这些URL读出并显示出来,也可以反过来向这个XML文件中写入加入的URL地址。很简单,却很实用,也足够来例示DOM的绝大部分用法了。
XML文件本身不复杂,就不给出它的DTD了。link.xml:
<?xml version="1.0" standalone="yes"?>
<links>
<link>
<text>JSP Insider</text>
<url newWindow="no">http://www.jspinsider.com</url>
<author>JSP Insider</author>
<date>
<day>2</day>
<month>1</month>
<year>2001</year>
</date>
<description>A JSP information site.</description>
</link>
<link>
<text>The makers of Java</text>
<url newWindow="no">http://java.sun.com</url>
<author>Sun Microsystems</author>
<date>
<day>3</day>
<month>1</month>
<year>2001</year>
</date>
<description>Sun Microsystem's website.</description>
</link>
<link>
<text>The standard JSP container</text>
<url newWindow="no">http://jakarta.apache.org</url>
<author>Apache Group</author>
<date>
<day>4</day>
<month>1</month>
<year>2001</year>
</date>
<description>Some great software.</description>
</link>
</links>
第一个程序我们称为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<links.getLength();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的内容就被写入到文件中去了。
发表评论
-
The processing instruction target matching "[xX][mM][lL]" is n...
2011-11-30 17:03 2941The processing instruction ta ... -
解决java.io.UTFDataFormatException: Invalid byte 1 of 1-byte UTF-8 sequence.
2009-12-24 14:44 4385原来是文件编码问题,另存下utf-8格式就好了 -
获得xml的节点属性
2009-03-18 18:40 1126获得xml的节点属性 -
How to transform DOM into String
2009-02-26 16:24 1177/** * Prints a textual repres ... -
DOM解析XML实例
2009-02-26 16:06 2449去年做了一年的项目, ...
相关推荐
Java与XML联合编程的核心在于将XML文档转换为可操作的对象模型,这就是DOM(Document Object Model)的作用。DOM是一种标准,它定义了一种树形结构来表示XML文档,并提供了API以便程序能够读取、修改和创建XML文档。...
总的来说,DOM在Java与XML的联合编程中提供了一种强大且灵活的机制,使得开发者可以方便地解析、创建和修改XML文档。通过深入理解和熟练运用DOM,可以提高XML处理的效率和代码的可维护性。在实际项目中,选择适合的...
### Java与XML联合编程之SAX篇 #### SAX概述 SAX(Simple API for XML)是一种用于解析XML文档的技术,虽然并非由W3C官方发布,但在实际应用中被广泛采纳,成为了一种非正式的标准。SAX适用于文档非常大的情况,...
这个“java+xml联合编程简单例子”很可能包含了一个简单的Java应用程序,该程序使用了XML来存储或传递数据,并通过Java的API来解析和处理这些XML数据。以下是一些可能涉及的关键知识点: 1. **DOM(Document Object...
### Java与XML联合编程知识点详解 #### 一、引言 在现代软件开发中,XML(Extensible Markup Language,可扩展标记语言)作为一种通用的数据交换格式,在不同平台间传输数据时发挥着重要作用。Java作为一门广泛应用...
Java与XML的交互是开发中常见的情景,特别是在处理配置文件、数据交换或者...了解和掌握DOM模型以及相关的API,对于进行XML编程至关重要。在实际开发中,根据需求选择合适的XML处理技术,能够提高代码的效率和灵活性。
在Java编程中,XML(可扩展标记语言)是一种被广泛用于数据存储和交换的格式,尤其是在Web服务和配置文件中。本笔记将深入探讨如何使用DOM(文档对象模型)和DOM4J库来创建XML文档。 一、DOM解析器 DOM是W3C推荐的...
Java的XML编程主要涉及到对XML文档的解析、创建和修改,而DOM(Document Object Model)是一种常见的处理XML的标准API。本教程重点讲解基于DOM的Java XML编程基础操作,旨在通过简单示例帮助开发者掌握XML的基本读写...
Java DOM(Document Object Model)是一种基于树形结构的XML文档处理模型,它允许程序员通过对象接口来访问和操作XML文档的各个部分。DOM为XML文档提供了一种内存中的表示方式,使得开发人员可以方便地创建、修改和...
Java XML编程指南旨在帮助开发者掌握在Java环境中处理XML(可扩展标记语言)的技能。XML是一种通用的数据交换格式,常用于存储和传输结构化数据。本指南将深入探讨如何在Java应用程序中有效地读取、解析、创建和操作...
《Java and XML(英文第三版)_java_xml_birdsolc_源码》是关于Java与XML集成编程的一本权威指南,特别适合于那些希望深入理解如何在Java应用程序中有效地使用XML技术的开发者。这本书详细阐述了Java平台上的XML处理...
《Java XML编程指南》是一本面向Java开发人员的实用教程,旨在帮助读者深入理解XML(eXtensible Markup Language)在Java环境中的应用。XML作为一种数据交换格式,因其灵活性和可扩展性,广泛用于Web服务、配置文件...
总的来说,DOM4J与XStream这两个库组合使用,可以帮助Java开发者高效地处理XML文档,实现数据的序列化和反序列化。在实际开发中,它们广泛应用于配置文件的读取、Web服务的交互、数据的持久化等多个领域。正确理解和...
Java 解析 XML 并导入数据库(DOM4J) Java 解析 XML 并导入数据库是指使用 Java 语言将 XML 文件解析并将其内容导入到数据库中。下面是使用 DOM4J 库来实现此功能的相关知识点: 一、XML 文件解析 XML...
Java XML编程指南主要涵盖的是如何在Java环境中处理XML(可扩展标记语言)文档的技术和实践。XML作为一种数据交换和存储格式,在Web服务、配置文件、数据序列化等领域广泛应用。本指南将深入探讨Java与XML的集成,...
Java XML编程指南主要涵盖的是如何在Java环境中处理XML(可扩展标记语言)文档的技术和方法。XML作为一种数据交换和存储格式,广泛应用于不同系统之间的数据交互,如Web服务、配置文件、数据序列化等。本指南将深入...