24.
25.Element node=(Element) nl.item(i);
26.
27.System.out.print("NAME:
");
28.
29.System.out.println (node.getElementsByTagName("NAME").item(0).getFirstChild().getNodeValue());
30.
31.……
32.
33.System.out.println();
34.
35.}
36.
37.}catch(Exception e){e.printStackTrace();}
38.
39.}
40.
41.}
程序详解:
1)DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
•我们在这里使用DocumentBuilderFacotry的目的是为了创建与具体解析器无关的程序,当DocumentBuilderFactory 类的静态方法newInstance()被调用时,它根据一个系统变量来决定具体使用哪一个解析器。
又因为所有的解析器都服从于JAXP所定义的接口,所 以无论具体使用哪一个解析器,代码都是一样的。
所以当在不同的解析器之间进行切换时,只需要更改系统变量的值,而不用更改任何代码。
这就是工厂所带来的好处。
2)•DocumentBuilder db = dbf.newDocumentBuilder();
•当获得一个工厂对象后,使用它的静态方法newDocumentBuilder()方法可以获得一个DocumentBuilder对象,这个对象代表了具体的DOM解析器。
但具体是哪一种解析器,微软的或者IBM的,对于程序而言并不重要
3)然后,我们就可以利用这个解析器来对XML文档进行解析了
•Document doc = db.parse("c:
/xml/message.xml");
•DocumentBuilder的parse()方法接受一个XML文档名作为输入参数,返回一个Document对象,这个Document对象就代表了一个XML文档的树模型。
以后所有的对XML文档的操作,都与解析器无关,直接在这个Document对象上进行操作就可以了。
而具体对Document操作的方法,就是由DOM所定义的了
4).从上面得到的Document对象开始,我们就可以开始我们的DOM解析了。
使用Document对象的getElementsByTagName()方法,我们可以得到一个NodeList对象,一个Node对象代表了一个XML文档中的一个标签元素,而NodeList对象,所代表的是一个Node对象的列表
NodeList nl = doc.getElementsByTagName("message"); •我们通过这样一条语句所得到的是XML文档中所有标签对应的Node对象的一个列表。
然后,我们可以使用NodeList对象的item()方法来得到列表中的每一个Node对象
•Node my_node = nl.item(0);
5).当一个Node对象被建立之后,保存在XML文档中的数据就被提取出来并封装在这个Node中了。
在这个例子中,要提取Message标签内的内容,我们通常会使用Node对象的getNodeValue()方法
•Stringmessage
=my_node.getFirstChild().getNodeValue();
注意:
请注意,这里还使用了一个getFirstChild()方法来获得message下面的第一个子Node对象。
虽然在message标签下面除了文本外并没有其它子标签或者属性,但是我们坚持在这里使用getFirstChild()方法,这主要和W3C对DOM的定义有关。
W3C把标签内的文本部分也定义成一个Node,所以先要得到代表文本的那个Node,我们才能够使用getNodeValue()来获取文本的内容
6.dom基本对象详解
DOM的基本对象有5个:
Document,Node,NodeList,Element和Attr
Document对象代表了整个XML的文档,所有其它的Node,都以一定的顺序包含在Document对象之内,排列成一个树形的结构,程序员可以通过遍历这颗树来得到XML文档的所有的内容,这也是对XML文档操作的起点。
我们总是先通过解析XML源文件而得到一个Document对象,然后再来执行后续的操作。
此外,Document还包含了创建其它节点的方法,比如createAttribute()用来创建一个Attr对象。
它所包含的主要的方法有
1).createAttribute(String):
用给定的属性名创建一个Attr对象,并可在其后使用setAttributeNode方法来放置在某一个Element对象上面。
•2)createElement(String):
用给定的标签名创建一个Element对象,代表XML文档中的一个标签,然后就可以在这个Element对象上添加属性或进行其它的操作。
•3)createTextNode(String):
用给定的字符串创建一个Text对象,Text对象代表了标签或者属性中所包含的纯文本字符串。
如果在一个标签内没有其它的标签,那么标签内的文本所代表的Text对象是这个Element对象的唯一子对象。
4)getElementsByTagName(String):
返回一个NodeList对象,它包含了所有给定标签名字的标签。
5)getDocumentElement():
返回一个代表这个DOM树的根元素节点的Element对象,也就是代表XML文档根元素的那个对象。
7.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对象
8 Element对象代表的是XML文档中的标签元素,继承于Node,亦是Node的最主要的子对象。
在标签中可以包含有属性,因而Element对象中有存取其属性的方法,而任何Node中定义的方法,也可以用在Element对象上面。
•getElementsByTagName(String):
返回一个NodeList对象,它包含了在这个标签中其下的子孙节点中具有给定标签名字的标签。
•getTagName():
返回一个代表这个标签名字的字符串。
•getAttribute(String):
返回标签中给定属性名称的属性的值。
在这儿需要注意的是,因为XML文档中允许有实体属性出现,而这个方法对这些实体属性并不适用。
这时候需要用到getAttributeNode()方法来得到一个Attr对象来进行进一步的操作
•getAttributeNode(String):
返回一个代表给定属性名称的Attr对象。
9.Attr对象代表了某个标签中的属性。
Attr继承于Node,但是因为Attr实际上是包含在Element中的,它并不能被看作是Element的子对象,因而在DOM中Attr并不是DOM树的一部分,所以Node中的getparentNode(),getpreviousSibling()和getnextSibling()返回的都将是null。
也就是说,Attr其实是被看作包含它的Element对象的一部分,它并不作为DOM树中单独的一个节点出现。
这一点在使用的时候要同其它的Node子对象相区别
SAX解析
SAX的全称是Simple APIs for XML,SAX提供的访问模式是一种顺序模式,这是一种快速读写XML数据的方式。
当使用SAX分析器对XML文档进行分析时,会触发一系列事件,并激活相应的事件处理函数,应用程序通过这些事件处理函数实现对XML文档的访问,因而SAX接口也被称作事件驱动接口。
由于SAX分析器实现简单,对内存要求比较低,因此实现效率比较高,对于那些只需要访问XML文档中的数据而不对文档进行更改的应用程序来说,SAX分析器更为合适。
SAX(Simple APIs for XML),面向XML的简单APIs。
使用DOM解析XML时,首先将XML文档加载到内存当中,然后可以通过随机的方式访问内存中的DOM树;SAX是基于事件而且是顺序执行的,一旦经过了某个元素,我们就没有办法再去访问它了,SAX不必事先将整个XML文档加载到内存当中,因此它占据内存要比DOM小,对于大型的XML文档来说,通常会使用SAX而不是DOM进行解析。
SAX也是使用的观察者模式(类似于GUI中的事件)
图中最上方的SAXParserFactory用来生成一个分析器实例。
XML文档是从左侧箭头所示处读入,当分析器对文档进行分析时,就会触发在DocumentHandler,ErrorHandler,DTDHandler以及EntityResolver接口中定义的回调方法。
4.SAX是事件驱动的,文档的读入过程就是SAX的解析过程。
在读入的过程中,遇到不同的项目,解析器会调用不同的处理方法。
5.org.xml.sax.helpers.DefaultHandler类的方法
项目
处理方法
文档开始
startDocument()
startElement()
“Tony Blair”
characters()
endElement()
文档结束
endDocument()
6.SAX方式提取XML文档内容信息示例
[java] viewplaincopyprint?
1.package com.shengsiyuan.xml.sax;
2.
3.import java.io.File;
4.
5.import java.util.Stack;
6.
7.import javax.xml.parsers.SAXParser;
8.
9.import javax.xml.parsers.SAXParserFactory;
10.
11.import org.xml.sax.Attributes;
12.
13.import org.xml.sax.SAXException;
14.
15.import org.xml.sax.helpers.DefaultHandler;
16.
17.public class SaxTest2
18.
19.{
20.
21.public static void main(String[] args) throws Exception
22.
23.{
24.
25. //step1:
获得SAX解析器工厂实例
26.
27.SAXParserFactory factory = SAXParserFactory.newInstance();
28.
29. //step2:
获得SAX解析器实例
30.
31.SAXParser parser = factory.newSAXParser();
32.
33. //step3:
开始进行解析
34.
35.parser.parse(new File("student.xml"), new MyHandler2());
36.
37.}
38.
39.}
40.
41.class MyHandler2 extends DefaultHandler
42.
43.{
44.
45.private Stack stack = new Stack();
46.
47.private String name;
48.
49.private String gender;
50.
51.private String age;
52.
53.@Override
54.
55.public void startElement(String uri, String localName, String qName,
56.
57.Attributes attributes) throws SAXException
58.
59.{
60.
61.stack.push(qName);
62.
63.for(int i = 0; i < attributes.getLength(); i++)
64.
65.{
66.
67.String attrName = attributes.getQName(i);
68.
69.String attrValue = attributes.getValue(i);
70.
71.System.out.println(attrName + "=" + attrValue);
72.
73.}
74.
75.}
76.
77.@Override
78.
79.public void characters(char[] ch, int start, int length)
80.
81.throws SAXException
82.
83.{
84.
85.String tag = stack.peek();
86.
87.if("姓名".equals(tag))
88.
89.{
90.
91.name = new String(ch, start,length);
92.
93.}
94.
95.else if("性别".equals(tag))
96.
97.{
98.
99.gender = new String(ch, start, length);
100.
101.}
102.
103.else if("年龄".equals(tag))
104.
105.{
106.
107.age = new String(ch, start, length);
108.
109.}
110.
111.}
112.
113.@Override
114.
115.public void endElement(String uri, String localName, String qName)
116.
117.throws SAXException
118.
119.{
120.
121.stack.pop(); //表示该元素已经解析完毕,需要从栈中弹出
122.