`

dom4j递归遍历xml文件,适合各种复杂的xml文件

阅读更多

今天项目需要完成一个xml数据导入的功能。第一步就是解析上传的xml文件。本来想用SAX来解析的,可是看到要导入的xml文件,心一下子就凉了,文件节点格式没有丝毫的规律可言,退而求其次,决定使用dom4j解析。
其实感觉dom4j还是比较简单的,和正常的思维更加贴切。导入dom4j-1.6.1.jar后开始敲代码。
在这里xml文件就不贴出来了,比较长,结构很复杂。
这里讲一下dom4j的基本思路:先读xml文件,生成一个document实例。代码如下:
      SAXReader reader = new SAXReader();
      Document document = reader.read(filePath);//读取xml文档
得到文档的根节点:
       Element root = document.getRootElement();//得到xml文档根节点元素
获取根节点的子节点:
       List<Element> elementList = root.elements();
得到子节点之后就是自由发挥的时候了,比如遍历子节点得到子节点的结点名称和节点的值。
       Iterator<Element> it = elementList.iterator();
while (it.hasNext()){
Element element = it.next();
System.out.println("节点的名称" + element.getName() + "节点的值" + "element.getText()");

   }
上面都是基本的操作,简单讲一下,在这里主要讲的是无论在xml文件有多么复杂的情况下,只要xml文件是合法的,那么都可以一次性的解析出xml文件的节点名称和节点的值。
给出这个问题后,很自然的会想到递归,虽然屡次提醒自己,不要使用递归,但是在这里,递归真正的起到了苦口良药的作用。下面就是我的代码。

package com.love.uilts.xml;

import java.io.File;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

/**
*
* @author Administrator
* 采用Dom4j解析复杂的xml文件
*
*/
public class Dom4jParseXml {

/**
* Dom4j解析xml文件的代码片段
* @throws DocumentException
*/

//设置数据存储格式Map

private static Map<String , String> map = new HashMap<String, String>();

public static Map parseXml(File filePath) throws DocumentException{

Map<String , String> mapEle = new HashMap<String, String>();
//StringBuffer sb = new StringBuffer();
SAXReader reader = new SAXReader();
    Document document = reader.read(filePath);//读取xml文档
    Element root = document.getRootElement();//得到xml文档根节点元素,即最上层的"<xml>"
    //System.out.println("输出根节点元素的名字===" + root.getName());
   
    //循环遍历出更节点下面的子节点
    List<Element> elementList = root.elements();
   
   Iterator<Element> it = elementList.iterator();
   while (it.hasNext()){
   Element element = it.next();
  // System.out.println(element);
   mapEle = printEle(element);

   }
return mapEle;
}


public static Map printEle(Element ele){
//StringBuffer sb = new StringBuffer();
if(ele.elements().size()==0){

System.out.println("该节点没有子节点,打印出节点名称" + ele.getParent().getName() +"打印出节点的值" + ele.getText());
map.put(ele.getParent().getName() , ele.getText());
}
else{
List<Element> elementList = ele.elements();
Iterator<Element> it = elementList.iterator();
while(it.hasNext()){

printEle(it.next());
}
  
}
return map;
}
/**
* @param args
* 功能测试
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
File file = new File("d:/datafeature@iso19115@we66zihsdb.xml");
Map<String , String> mapEleList = new HashMap<String, String>();
//StringBuffer sb = new StringBuffer();
try {
mapEleList = Dom4jParseXml.parseXml(file);

//遍历map

Iterator<Entry<String, String>> it = mapEleList.entrySet().iterator();
while(it.hasNext()){

Entry<String , String> entry = it.next();

System.out.println(entry.getKey() +"-------"+entry.getValue());
}
//System.out.println(sb.toString());

} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}

}

上面代码中标成蓝色的代码片段就是一个递归方法,方法会判断,当前访问的节点有没有子节点,如果没有子节点,就将节点名称以及节点值存放到map中,如果存在子节点,那么继续调用该方法去判断该节点的子节点有没有子节点,如果没有就将该节点的子节点的节点名称和节点值存放到ap中,如果存在子节点,则继续调用该方法,知道所有不存在子节点的节点的节点名称和节点值都被存放到map中。

个人觉得这个递归方法还是比较有参考价值的。

分享到:
评论
2 楼 qwer120158285 2013-11-04  
果然,当xml里面有重复的标签,直接这样存入hashMap前面的标签内容会被后面的覆盖掉
1 楼 qwer120158285 2013-11-04  
如果xml节点中有多个重复的标签,但对应了不同的值。就这样存入hashMap会不会有什么不妥哦

相关推荐

Global site tag (gtag.js) - Google Analytics