<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<学生名册>
<学生 学号="1">
<姓名>张三</姓名>
<!-- haha -->
<性别>男</性别>
<年龄>20</年龄>
</学生>
<学生 学号="2">
<姓名>李四</姓名>
<性别>女</性别>
<年龄>19</年龄>
</学生>
<学生 学号="3">
<姓名>王五</姓名>
<性别>男</性别>
<年龄>21</年龄>
</学生>
</学生名册>
package com.syh.xml.dom;
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Attr;
import org.w3c.dom.Comment;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* 使用递归解析任意给定的一个xml文档并且将其内容输出到命令行上
* @author Administrator
*
*/
public class DomTest4 {
public static void main(String[] args) throws Exception {
// 获得 dom 解析器工厂(工厂的作用是用于创建具体的解析器)
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance() ;
// 获得具体的 DOM 解析器
DocumentBuilder db = dbf.newDocumentBuilder() ;
// 解析一个 xml 文档,获得 Docuement 对象(根节点)---这个相当于拿到了进入 XML 文档的入口。这里 XML 文档是相对路径
Document doc = db.parse(new File("student.xml")) ;
//获得根元素节点 ----> <学生名册>
Element rootEle = doc.getDocumentElement();
// 这个头部信息与递归没有用
System.out.println("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
//调用递归方法
parseElement(rootEle) ;
}
//递归解析
private static void parseElement(Element ele) {
//获得元素(标签)的名字
String tagName = ele.getNodeName() ;
//获得 ele (参数)下面的所有的孩子构成的一个 Node 列表
NodeList children = ele.getChildNodes() ;
//到这里解析可得到 ---> <学生 ——下一步是要解析这个元素有没有属性
System.out.print("<" + tagName);
//获得 ele (参数)元素的所有属性所构成的 NamedNodeMap 对象,需要对其进行判断
NamedNodeMap map = ele.getAttributes() ;
//如果该元素存在属性
if(null != map) {
for(int i = 0 ; i < map.getLength() ; i ++) {
//获得该元素的每一个属性
Attr attr = (Attr) map.item(i) ;
//分别获得属性名和属性值
String attrName = attr.getName() ;
String attrValue = attr.getValue() ;
System.out.print(" " + attrName + "=\"" + attrValue + "\"");
//上面的代码也可以写成:System.out.print(" " + attrName + "='" + attrValue + "'");
}
}
//到这里拼接成了---> <学生 学号="1">
System.out.print(">");
//这个时候开始遍历 children 的 "孩子"
for(int i = 0 ; i < children.getLength(); i ++) {
//这是拿到了 第 i 个孩子
Node node = children.item(i) ;
//获得节点的类型
short nodeType = node.getNodeType() ;
/**
* 下面的判断是必须
* 这里为什么要判断一下节点的类型呢?
* 因为在 DOM 解析 XML文档的时候, W3C将 元素、节点、文本(包括空格)、属性、注释等都当成了节点!
* 我们这里拿到了一个 "节点" 但是 对应到 XML 文档里却不知道具体是什么类型的了!所以在这里要首先判断一下节点的类型
*/
if(nodeType == Node.ELEMENT_NODE) {
/**
* 如果这里出现了类似 <学生 学号="1"> 的这种情况,应该调用刚才解析 <学生 学号="1"> 的方法
*/
// 因为进入到这个判断里面了,所以可以肯定的认为这个节点是一个 Element 所以可以进行一下强制转换
// 又因为这个是元素,所以继续递归。
parseElement((Element)node) ;
} else if (nodeType == Node.TEXT_NODE) {
//递归出口
/**
* 为什么这里是递归的出口呢?
* 因为只要是元素就递归,不管这个元素是多少层,可是这个层次有多么的深,最后的结果一定是一个文本,所以这里是递归的出口
*/
System.out.print(node.getNodeValue());
} else if (nodeType == node.COMMENT_NODE) { //判断节点是不是为注释
System.out.print("<!--");
Comment comment = (Comment) node ;
//获取注释的内容
String data = comment.getData() ;
System.out.print(data);
System.out.print("-->");
}
}
// 关闭这个节点(指--> <学生 学号="1">) , 这里打印的是 --> </学生>
System.out.print("</" + tagName + ">");
//到此这个遍历就结束了!
}
}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<学生名册>
<学生 学号="1">
<姓名>张三</姓名>
<!-- haha -->
<性别>男</性别>
<年龄>20</年龄>
</学生>
<学生 学号="2">
<姓名>李四</姓名>
<性别>女</性别>
<年龄>19</年龄>
</学生>
<学生 学号="3">
<姓名>王五</姓名>
<性别>男</性别>
<年龄>21</年龄>
</学生>
</学生名册>