博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Dom4j 学习笔记
阅读量:4310 次
发布时间:2019-06-06

本文共 23616 字,大约阅读时间需要 78 分钟。

dom4j 是一种解析 XML 文档的开放源代码 XML 框架。

本文主要记载了一些简单的使用方法。

一、xml文件的解析

dom4j既可以解析普通的xml文件,也可以解析一个InputStream,先看看xml文件长什么样子:

1
Java编程思想
80
张三
2
三国演义
30
罗贯中
3
红楼梦
35
曹雪芹
4
西游记
25
吴承恩
5
水浒传
30
施耐庵

通过读取这一段xml文件并解析,将xml文件中的内容存储到javabean中。

private List
bs; private Book b; //读取xml文件获得Document对象 @Test public void test1(){ try { //1.读取xml文件,获取document对象 SAXReader reader = new SAXReader(); Document document = reader.read(new File("F:\\test\\books.xml")); //2.获取根节点
Element root = document.getRootElement(); bs = new ArrayList
(); //3.迭代,获取根节点的所有子节点
for (Iterator
es = root.elementIterator(); es.hasNext();) { Element e = es.next(); b = new Book(); //4.再次迭代,获取子节点的子节点
for (Iterator
e_son = e.elementIterator();e_son.hasNext();) { Element ee = e_son.next(); if(ee.getName().equals("id")){ b.setId(Integer.parseInt(ee.getText().toString())); }else if(ee.getName().equals("name")){ b.setName(ee.getText()); }else if(ee.getName().equals("price")){ b.setPrice(Integer.parseInt(ee.getText())); }else if(ee.getName().equals("auhtor")){ b.setAuthor(ee.getText()); } } bs.add(b); } } catch (DocumentException e) { e.printStackTrace(); } for (Book bk : bs) { System.out.println(bk.getName()); } }

Book.java

public class Book {    private int id;    private String name;    private int price;    private String author;    private Detail detail;    private Attribute attribute;    public Attribute getAttribute() {        return attribute;    }    public void setAttribute(Attribute attribute) {        this.attribute = attribute;    }    public Detail getDetail() {        return detail;    }    public void setDetail(Detail detail) {        this.detail = detail;    }    public int getId() {        return id;    }    public void setId(int id) {        this.id = id;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getPrice() {        return price;    }    public void setPrice(int price) {        this.price = price;    }    public String getAuthor() {        return author;    }    public void setAuthor(String author) {        this.author = author;    }}

Attribute.java

public class Attribute {    private String category;    private String edition;    public String getCategory() {        return category;    }    public void setCategory(String category) {        this.category = category;    }    public String getEdition() {        return edition;    }    public void setEdition(String edition) {        this.edition = edition;    }}

Detail.java

public class Detail {    private String pressTime;    private String storyTime;    public String getPressTime() {        return pressTime;    }    public void setPressTime(String pressTime) {        this.pressTime = pressTime;    }    public String getStoryTime() {        return storyTime;    }    public void setStoryTime(String storyTime) {        this.storyTime = storyTime;    }}

这里写图片描述

好,我们稍微修改一下xml文件,再看看个该如何解析:

1
Java编程思想
80
张三
天朝
21世纪
2
三国演义
30
罗贯中
明朝
汉末
3
红楼梦
35
曹雪芹
清朝
不详
4
西游记
25
吴承恩
明朝
大唐
5
水浒传
30
施耐庵
明朝
大宋

又多了一层嵌套,看解析方式:

private List
bs; private Book b; private Detail detail; // 读取xml文件获得Document对象 @Test public void test1() { try { // 1.读取xml文件,获取document对象 SAXReader reader = new SAXReader(); Document document = reader.read(new File("F:\\test\\books.xml")); // 2.获取根节点
Element root = document.getRootElement(); bs = new ArrayList
(); // 3.迭代,获取根节点的所有子节点
for (Iterator
es = root.elementIterator(); es.hasNext();) {
Element e = es.next(); b = new Book(); // 4.再次迭代,获取子节点的子节点
for (Iterator
e_son = e.elementIterator(); e_son .hasNext();) { Element ee = e_son.next(); if (ee.getName().equals("id")) { b.setId(Integer.parseInt(ee.getText().toString())); } else if (ee.getName().equals("name")) { b.setName(ee.getText()); } else if (ee.getName().equals("price")) { b.setPrice(Integer.parseInt(ee.getText())); } else if (ee.getName().equals("auhtor")) { b.setAuthor(ee.getText()); } else if (ee.getName().equals("detail")) { detail = new Detail(); for (Iterator
ds = ee.elementIterator(); ds .hasNext();) { Element d = ds.next(); if (d.getName().equals("pressTime")) { detail.setPressTime(d.getText()); } else if (d.getName().equals("storyTime")) { detail.setStoryTime(d.getText()); } } b.setDetail(detail); } } bs.add(b); } } catch (DocumentException e) { e.printStackTrace(); } for (Book bk : bs) { System.out.println(bk.getName()+","+bk.getDetail().getPressTime()); } }

继续修改xml文件,为之添加属性:

1
Java编程思想
80
张三
天朝
21世纪
2
三国演义
30
罗贯中
明朝
汉末
3
红楼梦
35
曹雪芹
清朝
不详
4
西游记
25
吴承恩
明朝
大唐
5
水浒传
30
施耐庵
明朝
大宋

给每一个book都添加了属性,又该怎么遍历呢?attribute的遍历和element的遍历非常类似,看代码:

// 读取xml文件获得Document对象    @Test    public void test1() {        try {            // 1.读取xml文件,获取document对象            SAXReader reader = new SAXReader();            Document document = reader.read(new File("F:\\test\\books.xml"));            // 2.获取根节点
Element root = document.getRootElement(); bs = new ArrayList
(); // 3.迭代,获取根节点的所有子节点
for (Iterator
es = root.elementIterator(); es.hasNext();) {
Element e = es.next(); b = new Book(); book_attr = new lenve.test.Attribute(); for (Iterator
as = e.attributeIterator();as.hasNext();) {
Attribute attr = as.next(); if(attr.getName().equals("category")){ book_attr.setCategory(attr.getText()); }else if(attr.getName().equals("edition")){ book_attr.setEdition(attr.getText()); } } b.setAttribute(book_attr); // 4.再次迭代,获取子节点的子节点
for (Iterator
e_son = e.elementIterator(); e_son .hasNext();) { Element ee = e_son.next(); if (ee.getName().equals("id")) { b.setId(Integer.parseInt(ee.getText().toString())); } else if (ee.getName().equals("name")) { b.setName(ee.getText()); } else if (ee.getName().equals("price")) { b.setPrice(Integer.parseInt(ee.getText())); } else if (ee.getName().equals("auhtor")) { b.setAuthor(ee.getText()); } else if (ee.getName().equals("detail")) { detail = new Detail(); for (Iterator
ds = ee.elementIterator(); ds .hasNext();) { Element d = ds.next(); if (d.getName().equals("pressTime")) { detail.setPressTime(d.getText()); } else if (d.getName().equals("storyTime")) { detail.setStoryTime(d.getText()); } } b.setDetail(detail); } } bs.add(b); } } catch (DocumentException e) { e.printStackTrace(); } for (Book bk : bs) { System.out.println(bk.getName()+","+bk.getDetail().getPressTime()+","+bk.getAttribute().getCategory()); } }

如果我们只想遍历某一个节点呢?比如我们只想遍历名称为id的节点,该怎么办?

private List
bs; private Book b; @Test public void test2() { try { // 1.读取xml文件,获取document对象 SAXReader reader = new SAXReader(); Document document = reader.read(new File("F:\\test\\books.xml")); // 2.获取根节点
Element root = document.getRootElement(); bs = new ArrayList
(); // 3.迭代,获取根节点的所有子节点
for (Iterator
es = root.elementIterator(); es.hasNext();) { Element e = es.next(); b = new Book(); // 4.再次迭代,获取子节点的子节点
for (Iterator
e_son = e.elementIterator("id"); e_son .hasNext();) { Element ee = e_son.next(); b.setId(Integer.parseInt(ee.getText().toString())); } bs.add(b); } } catch (DocumentException e) { e.printStackTrace(); } for (Book bk : bs) { System.out.println(bk.getId()+","+bk.getAuthor()); } }

输出:

这里写图片描述

最后一个问题,怎样以字符串的形式拿到一个xml文件:

@Test    public void test3(){        try {            SAXReader reader = new SAXReader();            Document document = reader.read(new File("F:\\test\\books.xml"));            String text = document.asXML();            System.out.println(text);        } catch (DocumentException e) {            e.printStackTrace();        }    }

二、使用程序写一个xml文件

1.怎样把一个字符串文件写成xml文件:

@Test    public void test4() {        try {            String text = "
苹果
red
3元
"; Document document = DocumentHelper.parseText(text); //两种方式皆可// FileWriter out = new FileWriter(new File("F:\\test\\str2xml.xml")); PrintWriter out = new PrintWriter(new File("F:\\test\\s2x.xml")); document.write(out); out.close(); } catch (DocumentException e) { e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }

这样输出的xml文件没有格式,可读性较差,换个方式再看看:

@Test    public void test5() {        try {            String text = "
苹果
red
3元
"; Document document = DocumentHelper.parseText(text); PrintWriter out = new PrintWriter(new File("F:\\test\\s2x1.xml")); XMLWriter writer = new XMLWriter(out, new OutputFormat().createPrettyPrint()); writer.write(document); writer.close(); } catch (DocumentException e) { e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }

输出结果:

这里写图片描述

这样的输出格式也是极好的。

2.通过程序一个元素一个元素的写入:

@Test    public void test6(){        int res = createXMLFile();        if(res==1){            System.out.println("xml文件创建成功!");        }else{            System.out.println("xml文件创建失败!");        }    }    public int createXMLFile(){        //返回0表示创建成功,返回1表示创建失败        int result = 0;        Document document = DocumentHelper.createDocument();        //建立根节点        Element root = document.addElement("fruits");        //加入注释        root.addComment("this is a xml about fruit");        Element f1 = root.addElement("fruit");        f1.addAttribute("color", "red");        Element f11 = f1.addElement("price");        f11.setText("10元");        Element f12 = f1.addElement("shape");        f12.setText("圆形");        Element f13 = f1.addElement("name");        f13.setText("苹果");        //将xml写入文件中        try {            PrintWriter out = new PrintWriter(new File("F:\\test\\111.xml"));            XMLWriter writer = new XMLWriter(out, new OutputFormat().createPrettyPrint());            writer.write(document);            writer.close();            result = 1;        } catch (FileNotFoundException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }        return result;    }

这里写图片描述

再看看新创建的xml文件长什么样:

这里写图片描述

这里使用最多的就是三个方法,一个是addElement(),一个是addAttribute(),还有一个是setText(),对每一个节点都可以执行这三个操作,你想创建的任何形状的xml都可以通过层层的嵌套实现。

如果想手动指定输出编码格式:

@Test    public void test6(){        int res = createXMLFile();        if(res==1){            System.out.println("xml文件创建成功!");        }else{            System.out.println("xml文件创建失败!");        }    }    public int createXMLFile(){        //返回0表示创建成功,返回1表示创建失败        int result = 0;        Document document = DocumentHelper.createDocument();        //建立根节点        Element root = document.addElement("fruits");        //加入注释        root.addComment("this is a xml about fruit");        Element f1 = root.addElement("fruit");        f1.addAttribute("color", "red");        Element f11 = f1.addElement("price");        f11.setText("10元");        Element f12 = f1.addElement("shape");        f12.setText("圆形");        Element f13 = f1.addElement("name");        f13.setText("苹果");        //将xml写入文件中        try {            PrintWriter out = new PrintWriter(new File("F:\\test\\111.xml"));            OutputFormat format = OutputFormat.createPrettyPrint();//缩进显示            //默认输出编码是UTF-8,可以手动设置为GBK            format.setEncoding("GBK");            XMLWriter writer = new XMLWriter(out, format);            writer.write(document);            writer.close();            result = 1;        } catch (FileNotFoundException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }        return result;    }

输出的xml文件为(注意看编码):

这里写图片描述

三、修改xml文件

我们要修改一下xml文件:

1
Java编程思想
80
张三
天朝
21世纪
2
三国演义
30
罗贯中
明朝
汉末
3
红楼梦
35
曹雪芹
清朝
不详
4
西游记
25
吴承恩
明朝
大唐
5
水浒传
30
施耐庵
明朝
大宋

1.把所有的edition属性的值为8的修改为100

使用xpath查找对象时,依赖于jaxen.jar包,所以要先这个包。查找对象时,如果查找的是节点,直接写名称,如:/books/book/name,如果查找的是属性,要在属性前加上@,如:/books/book/@edition

@Test    public void modifyXmlFile(){        try {            SAXReader reader = new SAXReader();            Document document = reader.read(new File("F:\\test\\books.xml"));            //先利用xpath查找对象            List
ns = document.selectNodes("/books/book/@edition"); Iterator
iter = ns.iterator(); while(iter.hasNext()){ Attribute attr = (Attribute) iter.next(); if(Integer.parseInt(attr.getValue())==8){ attr.setValue("100"); } } //输出修改后的文件 PrintWriter out = new PrintWriter(new File("F:\\test\\m1.xml")); XMLWriter w = new XMLWriter(out,OutputFormat.createPrettyPrint()); w.write(document); w.close(); } catch (DocumentException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }

2.把“Java编程思想”修改为“Java语言程序设计”并在该name属性所在的book节点中添加buyTime节点,节点值为2015-04-27:

@Test    public void modifyXmlFile(){        try {            SAXReader reader = new SAXReader();            Document document = reader.read(new File("F:\\test\\books.xml"));            //先利用xpath查找对象            List
ns = document.selectNodes("/books/book/name"); Iterator
iter = ns.iterator(); while(iter.hasNext()){ Element e = (Element) iter.next(); if(e.getText().equals("Java编程思想")){ e.setText("Java语言程序设计"); Element pe = e.getParent(); Element new_e = pe.addElement("buyTime"); new_e.setText("2015-04-27"); } } //输出修改后的文件 PrintWriter out = new PrintWriter(new File("F:\\test\\m2.xml")); XMLWriter w = new XMLWriter(out,OutputFormat.createPrettyPrint()); w.write(document); w.close(); } catch (DocumentException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }

3.若edition属性值为8,则删除该属性

@Test    public void modifyXmlFile(){        try {            SAXReader reader = new SAXReader();            Document document = reader.read(new File("F:\\test\\books.xml"));            List
ns = document.selectNodes("/books/book/@edition"); Iterator
iter = ns.iterator(); while(iter.hasNext()){ Attribute attr = (Attribute) iter.next(); if(Integer.parseInt(attr.getValue())==8){ attr.getParent().remove(attr); } } try { PrintWriter out = new PrintWriter(new File("F:\\test\\m3.xml")); XMLWriter w = new XMLWriter(out,OutputFormat.createPrettyPrint()); w.write(document); w.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } catch (DocumentException e) { e.printStackTrace(); } }

4.把id为3的书的name节点删除:

@Testpublic void modifyXmlFile(){    try {        SAXReader reader = new SAXReader();        Document document = reader.read(new File("F:\\test\\books.xml"));        List
ns = document.selectNodes("/books/book/id"); Iterator
iter = ns.iterator(); while(iter.hasNext()){ Element e = (Element) iter.next(); if(e.getText().equals("3")){ e.getParent().remove(e.getParent().element("name")); } } PrintWriter out = new PrintWriter(new File("F:\\test\\m4.xml")); XMLWriter w = new XMLWriter(out, OutputFormat.createPrettyPrint()); w.write(document); w.close(); } catch (DocumentException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }}

5.移除所有文件的id属性:

方式一:

直接查找id节点,再删除

@Test    public void modifyXmlFile(){        try {            SAXReader reader = new SAXReader();            Document document = reader.read(new File("F:\\test\\books.xml"));            List
ns = document.selectNodes("/books/book/id"); Iterator
iter = ns.iterator(); while(iter.hasNext()){ Element e = (Element) iter.next(); e.getParent().remove(e); } PrintWriter out = new PrintWriter(new File("F:\\test\\m5.xml")); XMLWriter w = new XMLWriter(out,OutputFormat.createPrettyPrint()); w.write(document); w.close(); } catch (DocumentException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }

方法二:

查找book节点,再删除book节点的id节点:

@Test    public void modifyXmlFile(){        try {            SAXReader reader = new SAXReader();            Document document = reader.read(new File("F:\\test\\books.xml"));            List
ns = document.selectNodes("/books/book"); Iterator
iter = ns.iterator(); while(iter.hasNext()){ Element e = (Element) iter.next(); e.remove(e.element("id")); } PrintWriter out = new PrintWriter(new File("F:\\test\\m6.xml")); XMLWriter w = new XMLWriter(out,OutputFormat.createPrettyPrint()); w.write(document); w.close(); } catch (DocumentException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }

好了,先写这么多,这些东东基本上够项目使用了。

转载于:https://www.cnblogs.com/qitian1/p/6461875.html

你可能感兴趣的文章
构建你的第一个App
查看>>
Network Mapper 嗅探工具
查看>>
linux下定时执行任务的方法
查看>>
ASP.NET MVC 常用内置验证特性 简介
查看>>
tuple有无list对key的影响
查看>>
java study3
查看>>
优秀的后台管理界面设计案例分享
查看>>
在VIM中使用GDB调试 – 使用vimgdb
查看>>
数据挖掘中哪些算法使用率较高?
查看>>
编程算法 - 推断二叉树是不是平衡树 代码(C)
查看>>
MySpring dataSource从配置文件获取
查看>>
矩阵的转置
查看>>
如何为SharePoint文档库、文件夹、文件单独设置权限
查看>>
【Linux】linux中很有用的指令(练习)
查看>>
C# 抽象(2)
查看>>
mysql之引擎、Explain、权限详解
查看>>
推荐-zabbix原理篇
查看>>
160809329 仲兆鹏 3
查看>>
HDOJ1013【Digital Roots】
查看>>
HDOJ1078 FatMouse and Cheese【动态规划】-----武科大ACM暑期集训队选拔赛2题
查看>>