2.DOM
2.1解析XML
目前最常用的XML解析技术:DOM和SAX
Sun公司提供了JAXP (Java API for XML)接口来使用DOM和SAX
org.w3c.dom:W3C推荐的用于使用DOM解析XML文档的接口
org.xml.sax:用于使用SAX解析XML文档的接口
javax.xml.parsers:解析器工厂工具,程序员获得并配置特殊的特殊语法分析器
2.2.1
使用DOM解析XML文档的步骤:
创建解析器工厂对象
由解析器工厂对象创建解析器对象
由解析器对象对指定XML文件进行解析,构建相应DOM树,创建Document对象
以Document对象为起点对DOM树的节点进行增删改查操作。
2.2.2
对象和方法
>Document对象代表了整个XML文档,所有其它的Node都以一定的顺序包含在Document对象之内,它也是对XML文档进行操作的起点
Document对象的主要方法有:
NodeListgetElementsByTagName(String):返回一个所有给定标签名字的标签NodeList对象.
getDocumentElement():返回一个代表这个DOM树的根元素的Element对象.
>NodeList对象指一个包含了一个或者多个节点(Node)的列表,可以简单的把它看成一个Node数组
NodeList对象常用的方法有:
getLength():返回列表的长度
item(int):返回指定位置的Node对象
>Node对象是DOM结构中最基本的对象,代表了文档树中的一个抽象节点,实际使用的时候,很少会真正用到Node这个对象,而是用到诸如Element、Attr、Text等Node对象的子对象
Node对象的主要方法有:
getChildNodes():包含此节点的所有子节点的NodeList
getFirstChild():如果节点存在子节点,则返回第一个子节点
getLastChild():如果节点存在子节点,返回最后一个子节点
getNextSibling():返回在DOM树中这个节点的下一个兄弟节点
getPrevIoUsSibling():返回在DOM树中这个节点的上一个兄弟节点
getNodeName():根据节点的类型返回节点的名称
getNodeValue():返回节点的值
getNodeType():返回节点的类型
>Element对象:代表XML文档中的标签元素,继承自Node对象,是Node最主要的子对象
Element对象的方法:
getAttribute(String):返回标签中给定属性名称的属性的值
getElementsByTagName(String):返回具有给定标记名称的所有后代 Elements 的 NodeList
资料:XMl中的空白符也会做为对象隐射在DOM中,因而,直接调用Node方法的getchildNodes方法有时会有些问题,有时不能够返回期望的NodeList元素列表
解决方法:
>使用Element的getElementByTagName(String),返回的nodelist就是所期待的对象了,然后调用item()提取想要的元素
>调用Node的getChildNodes方法得到NodeList对象,每次通过item()方法提取Node对象后判断node.getNodeType()=Node.element_node,既判断是否是元素节点,如果是true,表示是想要的元素
例1:
/**
* 使用DOM读取XML文档并输出道控制台
* @author YZB
*/
publicclass ReadXMl {
publicstaticvoid main(String[] args) {
// 1、得到DOM解析器的工厂实例
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
// 2、从DOM工厂获得DOM解析器
DocumentBuilder db = dbf.newDocumentBuilder();
// 3、解析XML文档,得到一个Document,即DOM树
Document doc = db.parse("pet3.xml");
// 4、得到所有<DOG>节点列表信息
NodeList dogList = doc.getElementsByTagName("dog");
System.out.println("xml文档中共有" + dogList.getLength() + "条狗狗信息");
// 5、轮循狗狗信息
for (int i = 0; i < dogList.getLength(); i++) {
// 5.1、获取第i个狗狗元素信息
Node dog = dogList.item(i);
Element element = (Element) dog;
String attrValue = element.getAttribute("id");
System.out.println("id:" + attrValue);
// 5.3、获取第i个狗狗元素的所有子元素的名称和值并输出
for (Node node = dog.getFirstChild(); node != null; node = node
.getNextSibling()) {
if (node.getNodeType() == Node.ELEMENT_NODE) {
String name = node.getNodeName();
String value = node.getFirstChild().getNodeValue();
System.out.print(name + ":" + value + "\t");
}
System.out.println();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
} catch (SAXException e) {
} catch (IOException e) {
例2:
* 使用DOM操作(增删改查)XML文档并输入XML文档中
*
publicclass DomConver {
DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
//添加节点
DocumentBuilder db=dbf.newDocumentBuilder();
Document doc=db.parse(new File("student.xml"));
Element eltstu=doc.createElement("student");
Element eltname=doc.createElement("name");
Element eltage=doc.createElement("age");
Text txtname=doc.createTextNode("王五");
Text txtage=doc.createTextNode("19");
eltname.appendChild(txtname);
eltage.appendChild(txtage);
eltstu.setAttribute("id","03");
eltstu.appendChild(eltname);
eltstu.appendChild(eltage);
//得到根节点
Element root=doc.getDocumentElement();
root.appendChild(eltstu);
//删除节点
NodeList nl=root.getElementsByTagName("student");
root.removeChild(nl.item(0));
//修改节点
Element eltstuchg=(Element) nl.item(0);
Node nodeagechg=eltstuchg.getElementsByTagName("age").item(0);
nodeagechg.getFirstChild().setNodeValue("22");
//显示信息
int len=nl.getLength();
for(int i=0;i<len;i++){
Element elt=(Element) nl.item(i);
System.out.println("编号:"+elt.getAttribute("id"));
Node nodename=elt.getElementsByTagName("name").item(0);
Node nodeage=elt.getElementsByTagName("age").item(0);
String name=nodename.getFirstChild().getNodeValue();
String age=nodeage.getFirstChild().getNodeValue();
System.out.println("姓名:"+name);
System.out.println("年龄:"+age);
System.out.println("--------------");
TransformerFactory tff=TransformerFactory.newInstance();
Transformer tf=tff.newTransformer();
tf.setOutputProperty("encoding","UTF-8");
DOMSource source=new DOMSource(doc);
StreamResult result=new StreamResult(new File("conver.xml"));
tf.transform(source,result);
// TODO Auto-generated catch block
} catch (TransformerConfigurationException e) {
} catch (TransformerException e) {
例3:
*获得节点的各个类型并输出
publicclass DomPrinter {
publicvoid printNodeInfo(Node node) {
System.out.println(node.getNodeName() + ":" + node.getNodeValue());
}
publicvoid printNode(Node node) {
Short nodetype = node.getNodeType();
switch (nodetype) {
case Node.PROCESSING_INSTRUCTION_NODE://指的是那一部分,API的哪呢
System.out.println("---PI start---");
printNodeInfo(node);
break;
case Node.ELEMENT_NODE:
System.out.println("---ELEMENT start---");
NamedNodeMap attrs = node.getAttributes();
for (int i = 0; i < attrs.getLength(); i++) {
Node attr = attrs.item(i);
System.out.println("-----Attribute start------");
printNodeInfo(attr);
System.out.println("-----Attribute end------");
case Node.TEXT_NODE:
System.out.println("---TEXT start---");
default:
Node child = node.getFirstChild();
while (child != null) {
printNode(child);
child = child.getNextSibling();
Document doc=db.parse(new File("student.xml"));
DomPrinter domprinter=new DomPrinter();
domprinter.printNode(doc);
附件:student.xml
<?xml version="1.0" encoding="gb2312"?>
<?xml-stylesheet type="text/xsl" href="student.xsl"?>
<students>
<student id="01">
<name>张三</name>
<age>18</age>
</student>
<name>李四</name>
<age>22</age>
</students>