dom4j是一个Java的XML API,是jdom的升级品,用来读写XML文件的。dom4j是一个十分优秀的JavaXML API,具有性能优异、功能强大和极其易使用的特点,它的性能超过sun公司官方的dom技术,同时它也是一个开放源代码的软件,可以在SourceForge上找到它。
使用时需要导入的包为:
<!-- https://mvnrepository.com/artifact/org.dom4j/dom4j -->
<dependency>
<groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>2.1.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/jaxen/jaxen -->
<dependency>
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
<version>1.1.6</version>
</dependency>
这个案例是获取节点名为BussinessData的最后两个节点的节点名和节点值,代码如下:
import org.apache.commons.lang3.StringUtils;
import org.dom4j.*;
import org.dom4j.io.SAXReader;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.*;
public interface DOM4JUtils {
// 解析books.xml文件
// 创建SAXReader的对象reader
static SAXReader reader = new SAXReader();
//返回值类型
static final StringBuilder stringBuilder = new StringBuilder();
static String parse(String str) {
//如果传入参数为空,返回null
if (StringUtils.isEmpty(str)) {
return null;
}
str = str.replaceAll("\\\n", "");
try {
byte[] bytes = str.getBytes("UTF-8");
InputStream is = new ByteArrayInputStream(bytes);
// 通过reader对象的read方法加载xml文件,获取docuemnt对象。
Document document = reader.read(is);
String path = "*//BussinessData";
//获取匹配的节点的下属节点
List<Node> nodes = document.selectNodes(path);
//新建一个栈
Stack<String> stack = new Stack<>();
//判断匹配的下属节点是否为空,循环往下匹配
while (!nodes.isEmpty()) {
path = path + "/*";
//每次获取的节点位置放入栈中
stack.push(path);
nodes = document.selectNodes(path);
}
//获取倒数第二个节点
for (int i = 0; i < 2; i++) {
stack.pop();
}
//获取倒数第二个节点的节点名
List<Node> nodes1 = document.selectNodes(stack.peek());
ArrayList<String> strings = new ArrayList<>();
for (Node node : nodes1) {
strings.add(node.getName());
}
//获取倒数第一个节点的值
for (String string : strings) {
List<Node> nodes2 = document.selectNodes("*//" + string + "/*");
stringBuilder.append(string).append("-");
for (Node node : nodes2) {
stringBuilder.append(node.getName()).append(":").append(node.getStringValue());
stringBuilder.append(",");
//
}
stringBuilder.append(";");
}
}catch (Exception e){
e.printStackTrace();
}
return stringBuilder.toString();
}
}
以上是通过节点匹配的方式进行xml文件遍历获取相应的节点名和节点值。但是在使用中会遇到xml文件标签不是成对出现的问题,使用节点匹配会出现异常。下面是通过节点根节点递归方式,匹配xml的节点和节点值:
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.*;
public class Dom4jTest {
// 解析xml文件
// 创建SAXReader的对象reader
private static SAXReader reader = new SAXReader();
//返回值类型
private static StringBuilder stringBuilder = new StringBuilder();
private static List<HashMap<String,String>> list = new ArrayList<>();
private static HashMap<String,String> hashMap = new HashMap<>();
public static void main(String[] args) {
StringBuilder stringBuilder1 = null;
//如果传入参数为空,返回null
if (StringUtils.isEmpty(str)) {
return null;
}
//替换掉传入参数的换行
str = str.replaceAll("\\\n", "");
try {
byte[] bytes = str.getBytes("UTF-8");
InputStream is = new ByteArrayInputStream(bytes);
// 通过reader对象的read方法加载xml文件,获取docuemnt对象。
Document document = reader.read(is);
//获取根节点下所有节点
Element rootElement = document.getRootElement();
iterateElement(rootElement);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 递归遍历所有节点
* @param element 需要遍历的节点
* @return 输出当前节点名称,当前节点值和当前节点的上一个节点
*/
private static void iterateElement(Element element) {
//获取当前节点下的所有节点
List<Element> elements = element.elements();
for (Element element1 : elements) {
//再次获取所有节点
List<Element> elements1 = element1.elements();
//如果当前节点下的节点数不为空
if (!elements1.isEmpty()){
//则重新调用方法进行遍历
iterateElement(element1);
}else {
//否则证明当前没有子节点,输出其上层节点名和当前节点名,当前节点值
System.out.println(element.getName()+":"+element1.getName()
+":"+element1.getStringValue());
}
}
}
}
}