使用递归解析任意给定的一个xml文档并且将其内容输出到命令行下(三)-其中的递归方法重点
使用递归解析任意给定的一个xml文档并且将其内容输出到命令行上(三)--其中的递归方法重点
<?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</年龄> </学生> </学生名册>