最近做练习开发的过程中,碰到了要在后端构建和解析xml的情况,在网上也有很多方法以及第三方包,简单的了解了一下后
就决定用Dom4J来开发了,跟大家分享一下我的学习经验。
理论上基本所有通过maven托管资源文件的情况都可以用这个方法。
1、在pox.xml写入相关及资源引用
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
<version>1.1.1</version>
</dependency>
注:上面两个包缺一不可,缺少一个包会导致在项目运行阶段dom4j不能加载相应类,但是在编译时候并不会报错。
配置资源前一定要检查是否已经导入相关资源,重复的资源和不同版本的同种资源都会导致相应架包不能被加载,同样不会在编译阶段报错,而是在项目运行阶段提示相关资源不存在。
遇到这种情况可以通过以下方法解决(不是100%管用):
去如下目录去删除相应资源文件在通过Maven更新项目(.m2文件不出意外一般都在<User>目录下)
2、开始使用
给已存在的xml中修改或追加内容(没有使用attribute相关)
想详细了解xml可以去如下网址:JavaWeb_xml学习。
创建新的XML:
private void CreateXml(String realPath) {
// 判断有无文件
File file = new File(realPath);
try {
if (!file.exists()) {//这里要保证文件上级目录都存在
//不存在的话先构建上级目录 - 这里realPath是文件目录不是文件夹目录
//文件夹目录在其他地方已经建好这里就不建了
Document doc = DocumentHelper.createDocument();//文档对象
Element prices = doc.addElement("prices");//创建第一个节点 视为根节点
//一般一个xml只存在一个根节点
Element price = prices.addElement("price");//为prices添加一个price子节点
price.addElement("firm", "哈哈");//为price添加四个子节点
price.addElement("area", "123");
price.addElement("first", "11");
price.addElement("extend", "as");
//创建xml文件 要上级目录都存在
FileWriter fileWriter = new FileWriter(realPath);
// 设置美观的缩进格式,便于阅读
OutputFormat format = OutputFormat.createPrettyPrint();
//避免出现中文乱码情况通过字节流输入到文件
XMLWriter writer = new XMLWriter(new FileOutputStream(file), format);//
writer.setWriter(fileWriter);
writer.write(doc);
writer.close();
}
} catch (Exception e) {
System.out.println("文件初始化失败、请检查文件");
}
}
结果如下:
遍历节点下某个子节点的值是否已经存在:
/**
* @param e prices根节点
* @param text 比对内容*/
private boolean IsExist(Element e, String text) {
if (text.equals(null) || "".equals(text))
return true;// 当名字为空时候 直接返回已存在 不修改空节点
@SuppressWarnings("unchecked")
List<Element> listAttr = e.elements();// 当前节点的所有属性 返回List集合
//这里是多个price节点的集合
if (listAttr.size() > 0) {
for (Element attr : listAttr) {// 遍历所有节点
org.dom4j.Node node = attr.selectSingleNode("firm");
if (!(node == null)) {//判断有子节点情况 以下是比对price节点中firm节点值与text比较
String value = attr.element("firm").getText();// 属性的值
if (value.equals(text)) {
//一个全局标记的price节点对象
//捕获该节点再修改属性值
repeatedE = attr;
return true;
} else if ("".equals(value)) {
return false;
}
}
}
}
return false;
}
向已存在的xml插入节点和修改节点值:
try {
SAXReader reader = new SAXReader();//xml阅读器
Document doc = reader.read(realPath); // 加载xml文件
Element prices = null;//根节点对象
try {
prices = doc.getRootElement();
} catch (Exception ex) {
System.out.println("异常信息:" + ex);
}
// 检验同名标签的是否存在 一定要在拿到根节点之后开始 多个根节点站不考虑
// 自动识别可以以后考虑 现在手动识别
//priceJsonsArray为资源 List集合 只起储存数据的作用 与dom4j没有直接关系
for (int i = 0; i < priceJsonsArray.length; i++) {
//判断有无相应节点
if (!IsExist(prices, priceJsonsArray[i].getFirm())) {
//没有的话添加一个price节点
Element a = prices.addElement("price");
a.addElement("firm").setText(priceJsonsArray[i].getFirm());
a.addElement("area").setText(priceJsonsArray[i].getArea());
a.addElement("first").setText(priceJsonsArray[i].getFirst());
a.addElement("extend").setText(priceJsonsArray[i].getExtend());
} else {
// 先获取当前节点 再修改值
repeatedE.element("firm").setText(priceJsonsArray[i].getFirm());
repeatedE.element("area").setText(priceJsonsArray[i].getArea());
repeatedE.element("first").setText(priceJsonsArray[i].getFirst());
repeatedE.element("extend").setText(priceJsonsArray[i].getExtend());
}
}
OutputFormat format = OutputFormat.createPrettyPrint(); // 设置美观的缩进格式,便于阅读
//format.setEncoding("UTF-8");
XMLWriter writer = new XMLWriter(new FileOutputStream(realPath), format);
writer.write(doc);
writer.close();
} catch (Exception e) {
// TODO: handle exception
}
结果如下:
读取xml也相对来说很简单了。
以上代码也仅仅起一个学习的作用,代码规范和代码重复度都很高,但是基本的作用都差不多了。