使用 dom4j 处理 xml (3)

今天想在使用 dom4j 选择节点时,顺便去重,可没有单独去重的方法;倒是有一个可以去重的,还必须提供一个 xpath 作为 排序和去重 的依据。

 1、xml 文件

<?xml version="1.0" encoding="UTF-8"?>
<tasks>
    <task name="work" delay="0" period="43200"></task>
    <task name="sleep" delay="3600" period="43200"></task>
    <task name="play" delay="120" period="604800"></task>
    <task name="play" delay="120" period="604800"></task>
</tasks>

2、用到的方法及参数说明:

 selectNodes 有 3 个重载方法,一个参数的、两个参数的,三个参数的。

 selectNode(String xpath1, String xpath2, String boolVal)

(1)xpath1:用来在文本中选择节点,并会返回一个结果集(List<Node>)。

(2)xpath2:站在结果中某个节点的角度,指出排序和去重的依据。

(3)0boolVal: 参数为 true 时,会对选择的结果进行去重处理。

呃……似乎有点不好理解,看例子吧。

3、测试代码及结果

Document doc = new SAXReader().read(new File("src/operxml/xmlfiles/tasks.xml"));

//
01、选择所有的 task 节点,按照节点的 name 属性排序,结果去重。 List<Node> tasks = doc.selectNodes("//task", "@name", true); tasks.forEach(tn -> System.out.println(tn.asXML()));

结果:

<task name="play" delay="120" period="604800"/>
<task name="sleep" delay="3600" period="43200"/>
<task name="work" delay="0" period="43200"/>
// 02、获取所有的任务名,按任务名排序和去重
//List<Node> taskNames = doc.selectNodes("//task/@name", "@name", true); //怎么选都只有一个节点。
List<Node> taskNames = doc.selectNodes("//task/@name", "../@name", true); //结果集中的节点是 task/@name,并没有什么属性可以用来排序;可以使用其父节点(task)的 name 属性来给结果排序 
taskNames.forEach(tn -> System.out.println(tn.asXML()));

结果:

name="play"
name="sleep"
name="work"
// 03、获取所有的任务名,按延迟排序和去重
List<Node> taskNames = doc.selectNodes("//task/@name", "../@delay", true); // 第二个参数作为排序依据、去重依据(很明显是根据 delay 排序的;与 02 相比较:02 中 name 有相同的,去重后只剩一个,03 中delay 各不相同。)
taskNames.forEach(tn -> System.out.println(tn.asXML()));

结果:

name="work"
name="play"
name="play"
name="sleep"

4、闲话:

本来想贴反编译的代码的,后来代码看到最后,出现了一个 new 1(this, sortValues)。费解啊!后来下载了 JD-GUI,打开 dom4j 的 jar 包,代码根本不是那样 。算了,不打算再分析一遍。

不过,这款叫 Enhanced Class Decompiler 的 eclipse 插件反编译出来的代码,格式确实让人不敢恭维,反编译出来的代码与 JD-GUI 的也会有不同。 

猜你喜欢

转载自www.cnblogs.com/Home-Artchy/p/xml_dom4j_3.html