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);

// 5.2、获取第i个狗狗元素的id属性的值并输出

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) {

e.printStackTrace();

} catch (SAXException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}

例2:

/**

*  使用DOM操作(增删改查)XML文档并输入XML文档中

* @author YZB

*

*/

publicclass DomConver {


publicstaticvoid main(String[] args) {

DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();

try {

//添加节点

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("--------------");

}

//把自己定义的节点添加到XML文件中

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);

} catch (ParserConfigurationException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (SAXException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

} catch (TransformerConfigurationException e) {

e.printStackTrace();

} catch (TransformerException e) {

e.printStackTrace();

}

}

}

例3:

/**

*获得节点的各个类型并输出

* @author YZB

*

*/

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);

System.out.println("---PI start---");

break;

case Node.ELEMENT_NODE:

System.out.println("---ELEMENT start---");

printNodeInfo(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------");

}

break;

case Node.TEXT_NODE:

System.out.println("---TEXT start---");

printNodeInfo(node);

System.out.println("---TEXT start---");

break;

default:

break;

}

Node child = node.getFirstChild();

while (child != null) {

printNode(child);

child = child.getNextSibling();

}

}

publicstaticvoid main(String[] args) {

DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();

try {

DocumentBuilder db=dbf.newDocumentBuilder();

Document doc=db.parse(new File("student.xml"));

DomPrinter domprinter=new DomPrinter();

domprinter.printNode(doc);

} catch (ParserConfigurationException e) {

e.printStackTrace();

} catch (SAXException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}

}


附件:student.xml

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>

<student id="01">

<name>李四</name>

<age>22</age>

</student>

</students>