解决问题需要,自己简单学习了一下dom4j 的基本用法:

(1)读取 xml 文件;

(2)修改 xml 文件。

需要的 jar 包:

  dom4j-xxx.jar (可以在 https://dom4j.github.io/ 下载)(不含 jaxen-xxx.jar)

  jaxen-xxx.jar (这个 jar 在 jdom 的下载(http://www.jdom.org/downloads/index.html)压缩文件中有)(如果用到 xpath,就必须引入此包,否则报 ClassNotFoundException)

1、读 xml 文件

(1)首先创建一个 xml 文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<!-- data info: -->
<!-- There're three classrooms where students from both class3 and class4 take courses in. -->
<!-- type equals 1, means the person is a teacher; 2 means student -->
<classes>
<classrooms>
<classroom name="J5C302"></classroom>
<classroom name="J5C301"></classroom>
<classroom name="J1C103"></classroom>
</classrooms> <persons>
<person type="1" name="AnYe Cao" cls="03" age="32">-------</person>
<person type="2" name="YiQing Zhang" cls="03" age="24" id="01130082">++++++++</person>
<person type="2" name="Ting Zhang" cls="03" age="22" id="01130081"></person>
<person type="2" name="ZhiHui Li" cls="03" age="23" id="01130065"></person>
<person type="2" name="LiuYang Pang" cls="03" age="24" id="01130066"></person>
<person type="2" name="DongYe Li" cls="03" age="21" id="01130068"></person> <person type="1" name="XueLi Chen" cls="04" age="15"></person>
<person type="2" name="ShengJun Ma" cls="04" age="27" id="01130092"></person>
<person type="2" name="Yan Cao" cls="04" age="20" id="01130099">
<a>aaa</a>
</person>
<dog>wang</dog>
</persons>
</classes>

(2)然后将文件读进内存并解析成 Document 对象:

         String filePath = "src/operxml/xmlfiles/classes.xml"; //这里是从本地的工程路径下读取

         SAXReader saxReader = new SAXReader();
Document document = saxReader.read(new File(filePath)); //SAXReader 不支持把一个字符串中解析成 Document。 DocumentHelper 可以!

(3)之后就是分析 Document 对象,比如具备某种特征的元素有多少个啊;比如获取某个节点的属性值啊。

   因为之前学习过 JQuery 选择器和 jsoup 来解析 html 文件,一上来就找有没有类似 jsoup 的那种筛选元素的API,发现只有一个 elementByID ,然而也没有理想中的效果!!

     Element elem = document.elementByID("01130082");
System.out.println(elem); //elementByID 一直返回 null,元素有 id 属性,但就是找不到;后来将id 改成大写的ID,就查到了。 据说也可以根据小写的id查到,但需要加个DTD什么的,没搞明白,以后再补。

  接下来说几个能用的:

 //1、遍历某个元素下的子元素(也可以使用elementIterator 迭代)
List<Element> elements = root.element("persons").elements(); //只能一级一级查找,如果路径深了就……
System.out.println(elements.get(0).getPath()); //取元素的xpath
for(Element ele : elements)
{
System.out.println(ele.asXML()); //转换xml成字符串
// System.out.println(ele.attributeValue("name") + ele.getText()); //读取当前元素的 name 属性及其中的文本
8         // ele.attributeValue("name","default"); //如果没有该属性或读取不到属性值,返回 "default" 
9         // ele.attribute("name"); //返回 Attribute 对象,而不是字符串。
}
 //2、通过 xpath获取指定节点
List<Node> nodes = root.selectNodes("/classes/persons/person"); //返回匹配 xpath 的所有后代节点;还有俩重载方法,好像还可以根据指定的比较规则去重
for(Node node : nodes)
{
System.out.println(node.asXML());
System.out.println(node.getStringValue()); //与getText()好像一样;相当于Element的 getText()
System.out.println(node.selectSingleNode("@type").asXML()); //因为属性一般不会重复,所以只取一个
System.out.println(node.selectSingleNode("@type").getText()); //获取属性值
}

(4)小结:

a. Element 与 Node 的区别
Element 强调的是部分与 xml 这个整体的关系,一个xml 文件是由一个个元素组成的。文档中可以出现哪些元素,什么类型的元素,都可能受 dtd, xsd约束的。一个元素指的大概就是一对闭合的标签,以及标签内的属性、文本。
Node 可以说弱化了类型的说法,分得更细。它可以是一个元素,也可以是元素的属性,还可以是元素中的文本,甚至是注释,所以有注释节点,文本节点,元素节点的说法。 举个例子:
  <class>
   <!-- 这是采矿 3 班的数据 -->
  <student name="xiaoming">小小明</student>
  <student name="xiaohong">小小红</student>
  </class>   例子中,整个class 可以看成一个元素,其下有两个子元素。
  例子中,整个class元素可以看成一个节点,节点中还包含一个注释节点,以及两个student 节点,每个student 节点还包含一个属性节点和文本节点。
b. getText() 和 getStringValue 的区别

举个例子:
Node singleNode = root.selectSingleNode("persons");
System.out.println(singleNode.getText()); //因为persons中都是子元素,并没有属于自己的innerText,所以取到的是空白符
System.out.println(singleNode.getStringValue()); //在persons以及persons的后代(不仅仅是子元素)元素中找innerText
2、修改 xml 文件

就是修改 Document 对象中的 Element (修改 子元素、属性、文本)。

 a.修改 元素中的 元素
     @Test
public void modifyAndWrite() throws Exception
{
String filePath = "src/operxml/xmlfiles/classes.xml"; SAXReader saxReader = new SAXReader();
Document document = null;
document = saxReader.read(new File(filePath));
document.setXMLEncoding("UTF-8");
Element root = document.getRootElement(); List<Element> elements = root.element("classrooms").elements("classroom");
Element ele0 = elements.get(0);
Element ele_cp = ele0.createCopy(); //或者使用 DocumentHelper.createElement
ele_cp.addAttribute("level", "Lv999"); //支持链式调用!! 如果添加了重复属性,那么只算一个属性,属性值覆盖。
ele_cp.remove(ele_cp.attribute("name"));
ele_cp.attributeValue("level", "Lv001");
ele_cp.setText("miao"); ele0.getParent().add(ele_cp);
ele0.getParent().remove(elements.get(1)); //将当前元素 从 直接父 元素中删除
 b.修改 元素中的 节点
   //01  从nodes中删除,nodes只是一个副本,此处删除并不会从Document中删除
List<Node> nodes = root.selectNodes("//mt:person" );
nodes.remove(2);
for(Node tmpNode : nodes)
{
Node node = tmpNode.selectSingleNode("@id");
if(null == node || (null != node && !node.getText().startsWith("0113008")))
{
// 02 将此节点从其父节点中删除;如果此节点为根节点,则将其从Document中删除
tmpNode.detach();
continue;
}
} // 03 只能从Element中删除 直接 子节点(如果不是直接子节点,则用detach)
root.remove(root.selectSingleNode("//mc:persons")); // 在document中删除了某些节点后,变化并不能同步到 nodes中;nodes可以作为之前的一个副本
// 将节点从Document中删除: Element.remove(Node) 或 Node.detach() System.out.println(document.asXML());
Node nod = root.selectSingleNode("//bme:classroom");
Node nod_cp = (Node) nod.clone();
nod_cp.selectSingleNode("@name").setName("nm"); //属性节点setName 无效;
nod_cp.selectSingleNode("@name").setText("eee"); //相当于设置该属性节点所在元素的 该属性值。使用之前最好判断一下有没有这个属性节点,不然就是空指针。
nod_cp.setName("clsroom"); //元素节点 修改元素的标签名、文本值
nod_cp.setText("ddd");
nod.getParent().add(nod_cp); //node.getParent 得到的是node 所在的元素。所以修改 xml 是对 Element 的修改。Node 本身没提供多少方法。 

 c. 将 Document 对象写入 xml 文件

 FileWriter fileWriter = new FileWriter(new File(filePath));
//1、这样输出没有格式
// document.write(fileWriter);
// fileWriter.flush();
// fileWriter.close(); //2、有格式地输出
OutputFormat printFormat = OutputFormat.createPrettyPrint();
printFormat.setEncoding("UTF-8");
printFormat.setIndent(" ");
XMLWriter xmlWriter = new XMLWriter(fileWriter, printFormat);
xmlWriter.write(document);
xmlWriter.flush();
fileWriter.close();
xmlWriter.close(); // SAXWriter saxWriter = new SAXWriter(); //SAXWriter不是用来将document写进硬盘的
// saxWriter.write(document);

3、总结 + 闲话

(1)基本用法主要就是几个常用的类: SAXReader、Document、Element、Node、OutputFormat、XMLWriter。

(2)修改 xml 文件,就是 读进来并解析成 Document对象,然后修改这个 Document 对象,再把 Document 对象写进xml文件;并不是直接在 xml 文件上改。

(3)xpath 功能很强,有些类似于 jquery 选择器。

使用 dom4j 处理 xml (1)的更多相关文章

  1. 使用dom4j读取xml连接数据库与之单例模式

    使用dom4j读取xml ,加入jar包 dom4j-1.6.1.jar jaxen-1.1-beta-6.jar public class XmlConfigReader { //懒汉式,延迟加载 ...

  2. Dom4j把xml转换成Map(固定格式)

    /** * 可解析list * * @param fileName * @return * @throws Exception */ @SuppressWarnings("unchecked ...

  3. 【dom4j xml】使用dom4j处理XML文件--测试过程遇到的问题

    首先 关于dom4j的API,有如下: 当然  其中的实体引用有以下: 测试使用环境: 使用Maven搭建web环境,pom.xml文件配置如下: <project xmlns="ht ...

  4. java中采用dom4j解析xml文件

    一.前言 在最近的开发中用到了dom4j来解析xml文件,以前听说过来解析xml文件的几种标准方式:但是从来的没有应用过来,所以可以在google中搜索dmo4j解析xml文件的方式,学习一下dom4 ...

  5. 转:在java中使用dom4j解析xml

    JAVA 使用Dom4j 解析XML Java DOM4J Parser - Parse XML Document Dom4j下载及使用Dom4j读写XML简介 在java中使用dom4j解析xml ...

  6. Dom4j解析xml

    public class Dom4jTest { // Dom4j解析xml // 因为所有的方法都需要Dom树 static Document document = null; static Ele ...

  7. 使用Dom4j进行XML解析

    1  概述 在进行ESB集成项目中,使用到了很多系统的接口,这些接口传输的数据大部分都采用了XML的格式,这样在使用ESB开发服务时就需要对XML数据进行解析或拼接的操作,本文以项目中流程服务为例,讲 ...

  8. 使用dom4j解析XML文档

    dom4j的包开源包,不属于JDK里面,在myeclipse中要单独导入在项目中,这里不累赘了 做这个过程,很慢,因为很多方法没用过不熟悉,自己得去查帮助文档,而且还得去试,因为没有中文版,英文翻译不 ...

  9. 【JAVA使用XPath、DOM4J解析XML文件,实现对XML文件的CRUD操作】

    一.简介 1.使用XPath可以快速精确定位指定的节点,以实现对XML文件的CRUD操作. 2.去网上下载一个“XPath帮助文档”,以便于查看语法等详细信息,最好是那种有很多实例的那种. 3.学习X ...

  10. 用DOM4J解析XML文件案例

    用DOM4J解析XML文件案例,由于DOM4J不像JAXP属于JAVASE里,所以如果要使用DOM4J,则必须额外引入jar包,如图:

随机推荐

  1. Codeforces.1043F.Make It One(DP 容斥)

    题目链接 \(Description\) 给定\(n\)个数\(A_i\),求最少选出多少个数,使得它们的\(\gcd\)为\(1\). \(n,A_i\leq3\times10^5\). \(Sol ...

  2. c#学习个人总结

    c#一门程序语言,我的专业课.有了一学期的接触对它的了解还只是皮毛,里面有许多的知识都有待了解学习和提高,熟练掌握程序的语法,能够熟练的调用,对于一些理论性的知识还需要今后更多的揣摩和研究,讲书本中的 ...

  3. 面试题: 多个 await 处理,有一个失败,就算作失败

    面试题: 多个 await 处理,有一个失败,就算作失败 ? Promise.all([p1, p2, p3....])    // 返回的也是一个 Promise 对象 -------- asait ...

  4. 27 ArcMap加载天地图服务一片空白怎么办

    在ArcMap中添加WMTS Server,连接上了,但是不显示 天地图升级向导:http://lbs.tianditu.gov.cn/authorization/authorization.html ...

  5. spring-boot+mybatisPlus+shiro的集成demo 我用了5天

    spring-boot + mybatis-plus + shiro 的集成demo我用了五天 关于shiro框架,我还是从飞机哪里听来的,就连小贱都知道,可我母鸡啊.简单百度了下,结论很好上手,比s ...

  6. JAVA新的一天

    在2019/03/22/今天里,荣幸成为这个班级的一员,认识了新的小伙伴们,上午由老师大体说了一下java的理念,下午安装了DW编辑器,以及讲解了HTML的基本构造,和标签的使用,即使以前学习过,这次 ...

  7. 2018-2019-2 20175320实验二《Java面向对象程序设计》实验报告

    2018-2019-2 20175320实验二<Java面向对象程序设计>实验报告 一.实验步骤及内容 (一)了解使用JUint,并对示例代码MyUtil进行测试 1.先在IDEA中安装J ...

  8. flex 左边固定宽度,右边自适应

    <div id="flex"> <div id="left">我在边,定宽</div> <div id="r ...

  9. [02-02 ]Java数据库链接范列

    /* 01 连接池版本的 数据库 连接管理工具,适合于并发场合 */ package cn.tedu.jdbc.day02; import java.io.InputStream; import ja ...

  10. python摸爬滚打之----tcp协议的三次握手四次挥手

    TCP协议的三次握手, 四次挥手 三次握手过程 1, 服务器时刻准备接受客户端进程的连接请求, 此时服务器就进入了LISTEN(监听)状态; 2, 客户端进程然后向服务器发出连接请求报文, 之后客户端 ...