当前项目使用quartz来进行任务调度。目前两种初始化任务有两种方式,一种是通过插件,以xml形式加载;一种通过代码动态加载。如果需要热部署,在内存中即可以动态增删任务但不会持久化,因此需要同时对XML的配置进行动态修改增删,防止重启时任务的改动丢失。
xml一直都是会用,而没有系统总结过,借此机会练习。查资料说dom4j各方面表现优异,就使用它来进行练习。
实际xml的操作无非就是读写增删改查。以下是需要注意的一些问题:
SAXReader读入文件流,得到Document不解释。注意读入文件路径,如xml在classes目录下,可以用Class.class.getResource("/").getPath()获取相对路径。
写:
XMLWriter写回磁盘。使用OutputFormat.createPrettyPrint指定输出格式为适合人看的缩进式,反之createCompactFormat为紧凑式。
写回时如有乱码,需要使用FileOutputStream。参考:http://chenlb.iteye.com/blog/122344
查找:
Element的selectNodes()使用xpath语法。类似jquery的选择器,xpath语法具体不说了,很方便筛选不同层次的节点。选择器有很多起始路径,需要谨慎指定// / . 等。有一些内置的语法,如name()指元素的名称,很灵活。
增加:
有的Document在增加结点时,会在节点属性中添加多余的xmlns。那是因为这份文档本身有指定的xmlns,只要在addElement(elementName, namespace)中将namespace指定为文档的xmlns即可。
删除
移除节点时一定是直接父节点来remove,即node.getParent().remove(node)。
相关配置:
dom4j使用xpath,因此需要引入jaxen包。否则会java.lang.NoClassDefFoundError: org/jaxen/JaxenException错误。
示例:
xml文件。test.xml
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns="http://blog.csdn.net/librasama">
<teacher>
<name>大码</name>
<age>32</age>
<category>普通</category>
<subject>语文</subject>
</teacher>
<teacher>
<name>大农</name>
<age>22</age>
<category>特级</category>
<subject>物理</subject>
</teacher>
<teacher>
<name>大苦</name>
<age>23</age>
<category>普通</category>
<subject>数学</subject>
</teacher>
<teacher>
<name>大逼</name>
<age>33</age>
<category>普通</category>
<subject>教务</subject>
</teacher>
</root>
java代码
package com.zoe;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Iterator;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
/**
* DOM4J操作XML的增删改查读写
* @author zoe
*
*/
public class DOM4J {
public static String TEST_XMLNS = "http://blog.csdn.net/librasama";
/**
* 测试
* @param args
*/
public static void main(String[] args) {
Document doc = read("test.xml");
Node n = getNode(doc, "大码");
System.out.println("查询大码节点:"+n.asXML());
addNode(doc, "神棍", "30", "特级", "体育");
write(doc, "result.xml");
System.out.println("新增神棍:");
System.out.println(doc.asXML());
deleteNode(doc, "大逼");
write(doc, "result.xml");
System.out.println("删除大逼:");
System.out.println(doc.asXML());
}
/**
* 读
* @param filename
*/
public static Document read(String filename) {
SAXReader reader = new SAXReader();
Document doc = null;
try {
doc = reader.read(new File(filename));
} catch (DocumentException e) {
e.printStackTrace();
}
return doc;
}
/**
* 写
* @param filename
*/
public static void write(Document doc, String filename) {
try {
FileOutputStream fos = new FileOutputStream(filename);
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter writer = new XMLWriter(fos, format);
writer.write(doc);
writer.close();//关闭资源
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 查
* @param filename
*/
public static Node getNode(Document doc, String name) {
List nodes = doc.selectNodes("//*[name()='teacher']");
Iterator iterator = nodes.iterator();
while(iterator.hasNext()) {
Node n = (Node)iterator.next();
Element e = (Element)n.selectSingleNode("./*[name()='name']");
if(e!= null && e.getText() != null && name.equals(e.getText())) {
return e;
}
}
return null;
}
/**
* 增
* @param name
* @param age
* @param category
* @param subject
*/
public static boolean addNode(Document doc,
String name, String age, String category, String subject) {
Element d = (Element)doc.selectNodes("//*[name()='root']").get(0);
Element e = d.addElement("teacher", TEST_XMLNS);
Element nameE = e.addElement("name", TEST_XMLNS);
nameE.setText(name);
Element ageE = e.addElement("age", TEST_XMLNS);
ageE.setText(age);
Element categoryE = e.addElement("category", TEST_XMLNS);
categoryE.setText(category);
Element subjectE = e.addElement("subject", TEST_XMLNS);
subjectE.setText(subject);
return true;
}
/**
* 删
* @param name
*/
public static boolean deleteNode(Document doc, String name) {
Node node = getNode(doc, name);
if(node != null) {
return node.getParent().remove(node);
}
return false;
}
}