Dom4j 学习笔记

来源:互联网 发布:thinksns app源码 编辑:程序博客网 时间:2024/06/14 03:59

dom4j 是一种解析 XML 文档的开放源代码 XML 框架。dom4j下载地址
本文主要记载了一些简单的使用方法。

一、xml文件的解析

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

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

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

    private List<Book> 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.获取根节点<books>            Element root = document.getRootElement();            bs = new ArrayList<Book>();            //3.迭代,获取根节点的所有子节点<book>            for (Iterator<Element> es = root.elementIterator(); es.hasNext();) {                Element e = es.next();                b = new Book();                //4.再次迭代,获取子节点的子节点<id><name><price><author>                for (Iterator<Element> 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文件,再看看个该如何解析:

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

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

    private List<Book> 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.获取根节点<books>            Element root = document.getRootElement();            bs = new ArrayList<Book>();            // 3.迭代,获取根节点的所有子节点<book>            for (Iterator<Element> es = root.elementIterator(); es.hasNext();) {                Element e = es.next();                b = new Book();                // 4.再次迭代,获取子节点的子节点<id><name><price><author>                for (Iterator<Element> 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<Element> 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文件,为之添加属性:

<books>    <book category="编程技术" edition="8">        <id>1</id>        <name>Java编程思想</name>        <price>80</price>        <author>张三</author>        <detail>             <pressTime>天朝</pressTime>             <storyTime>21世纪</storyTime>        </detail>    </book>    <book category="历史小说" edition="1">        <id>2</id>        <name>三国演义</name>        <price>30</price>        <author>罗贯中</author>        <detail>             <pressTime>明朝</pressTime>             <storyTime>汉末</storyTime>        </detail>    </book>    <book category="小说" edition="2">        <id>3</id>        <name>红楼梦</name>        <price>35</price>        <author>曹雪芹</author>        <detail>             <pressTime>清朝</pressTime>             <storyTime>不详</storyTime>        </detail>    </book>    <book category="神话小说" edition="4">        <id>4</id>        <name>西游记</name>        <price>25</price>        <author>吴承恩</author>        <detail>             <pressTime>明朝</pressTime>             <storyTime>大唐</storyTime>        </detail>    </book>    <book category="小说" edition="5">        <id>5</id>        <name>水浒传</name>        <price>30</price>        <author>施耐庵</author>        <detail>             <pressTime>明朝</pressTime>             <storyTime>大宋</storyTime>        </detail>    </book></books>

给每一个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.获取根节点<books>            Element root = document.getRootElement();            bs = new ArrayList<Book>();            // 3.迭代,获取根节点的所有子节点<book>            for (Iterator<Element> es = root.elementIterator(); es.hasNext();) {                Element e = es.next();                b = new Book();                book_attr = new lenve.test.Attribute();                for (Iterator<Attribute> 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.再次迭代,获取子节点的子节点<id><name><price><author>                for (Iterator<Element> 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<Element> 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<Book> 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.获取根节点<books>            Element root = document.getRootElement();            bs = new ArrayList<Book>();            // 3.迭代,获取根节点的所有子节点<book>            for (Iterator<Element> es = root.elementIterator(); es.hasNext();) {                Element e = es.next();                b = new Book();                // 4.再次迭代,获取子节点的子节点<id><name><price><author>                for (Iterator<Element> 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 = "<fruits><fruit><name>苹果</name><color>red</color><price>3元</price></fruit></fruits>";            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 = "<fruits><fruit><name>苹果</name><color>red</color><price>3元</price></fruit></fruits>";            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文件:

<books>    <book category="编程技术" edition="8">        <id>1</id>        <name>Java编程思想</name>        <price>80</price>        <author>张三</author>        <detail>             <pressTime>天朝</pressTime>             <storyTime>21世纪</storyTime>        </detail>    </book>    <book category="历史小说" edition="1">        <id>2</id>        <name>三国演义</name>        <price>30</price>        <author>罗贯中</author>        <detail>             <pressTime>明朝</pressTime>             <storyTime>汉末</storyTime>        </detail>    </book>    <book category="小说" edition="2">        <id>3</id>        <name>红楼梦</name>        <price>35</price>        <author>曹雪芹</author>        <detail>             <pressTime>清朝</pressTime>             <storyTime>不详</storyTime>        </detail>    </book>    <book category="神话小说" edition="4">        <id>4</id>        <name>西游记</name>        <price>25</price>        <author>吴承恩</author>        <detail>             <pressTime>明朝</pressTime>             <storyTime>大唐</storyTime>        </detail>    </book>    <book category="小说" edition="5">        <id>5</id>        <name>水浒传</name>        <price>30</price>        <author>施耐庵</author>        <detail>             <pressTime>明朝</pressTime>             <storyTime>大宋</storyTime>        </detail>    </book></books>

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<Node> ns = document.selectNodes("/books/book/@edition");            Iterator<Node> 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<Node> ns = document.selectNodes("/books/book/name");            Iterator<Node> 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<Node> ns = document.selectNodes("/books/book/@edition");            Iterator<Node> 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<Node> ns = document.selectNodes("/books/book/id");        Iterator<Node> 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<Node> ns = document.selectNodes("/books/book/id");            Iterator<Node> 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<Node> ns = document.selectNodes("/books/book");            Iterator<Node> 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();        }    }

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

0 0
原创粉丝点击