Dom4j学习

223 阅读3分钟

dom4j

Document Object Model

简介

java 的 xml 框架

api

示例

<root>
  <author name="James" location="UK">James Strachan</author>
  <author name="Bob" location="US">Bob McWhirter</author>
</root>

分析

  1. <root> 这个叫元素(Element),也叫标签
  2. <author name="James" ...> 中 name 叫属性(Attribute)
  3. James Strachan 叫元素内容,也叫文本

具体方法

// 获取根元素
Element rootElement = document.getRootElement() 
// 获取子元素的迭代器
rootElement.elementIterator(); 
// 获取名为author的子元素迭代器
rootElement.elementIterator("author"); 
// 获取名为author的第一个子元素
Element author1 = rootElement.element("author"); 
// 获取元素的属性迭代器
rootElement.attributeIterator(); 

// 获取元素内容
element.getText(); 
// 获取元素的名称,标签的名称
element.getName(); 
// 获取名为 name 的元素属性对象
Attribute nameAttr = element.attribute("name"); 
// 获取Attribute对象的值
nameAttr.getValue(); 

// 将 Document 或者 任何 Node(包括Attribute Element)转换成xml
String text = document.asXML();
// 将xml 格式的 string 转成 Document 
Document document = DocumentHelper.parseText(text);

高效操作

xpath导航

xpath 简介

  1. 基本的 XPath 语法类似于在一个文件系统中定位文件,如果路径以斜线 / 开始, 那么该路径就表示到一个元素的绝对路径
  2. 如果路径以双斜线 // 开头, 则表示选择文档中所有满足双斜线//之后规则的元素(无论层级关系)
  3. 属性通过前缀 @ 来指定

如果想详细了解xpath,可以去这个网站 Zvon tutorial

导航

// 快速找到所有 root - author 的结点
List<Node> nodes = document.selectNodes("//root/author");

/**
 * 示例:查找所有 a 标签的 url 
 */
public void findLinks(Document document) throws DocumentException {
    // 快速找到所有 a - @href 的结点
    List<Node> list = document.selectNodes("//a/@href");

    for (Iterator<Node> iter = list.iterator(); iter.hasNext();) {
        Attribute attribute = (Attribute) iter.next();
        String url = attribute.getValue();
    }
}

快速遍历

public void treeWalk(Element element) {
    for (int i = 0, size = element.nodeCount(); i < size; i++) {
        Node node = element.node(i);
        if (node instanceof Element) {
            treeWalk((Element) node);
        }
        else {
            // do something…
        }
    }
}

示例

创建xml文件

    private Document createXML(){
        // 创建一个Document对象表示整个文档
        Document document = DocumentHelper.createDocument();

        // 添加根节点
        Element serviceEle = document.addElement("service");

        // 添加注释,哪个标签调用添加注释的方法,就加在哪个上面
        serviceEle.addComment("这是一个service");

        // 在根节点serviceEle上添加子节点,不是文档结点serviceEle
        serviceEle.addElement("head");
        Element bodyEle = serviceEle.addElement("body");

        // body结点中添加 name结点
        Element nameEle = bodyEle.addElement("name");
        nameEle.addComment("借书人");
        // 设置name结点内容
        nameEle.addText("luck");
        // 添加属性内容
        nameEle.addAttribute("member", "false");

        // body结点中添加 books结点
        Element booksEle = bodyEle.addElement("books");
        Element bookEle = booksEle.addElement("book");
        Element titleEle = bookEle.addElement("title");
        titleEle.addText("dom4j tutorials");

        return document;
    }

    /**
     * 保存到文件
     * @param document 
     * @param path
     * @throws IOException
     */
    public void toFile(Document document, String path) throws IOException {
        XMLWriter xmlWriter = null;
        try{
            xmlWriter = new XMLWriter(new FileWriter(new File(path)));
            xmlWriter.write(document);
        }finally {
            if(xmlWriter != null){
                xmlWriter.close();
            }
        }
    }

    /**
     * 打印字符串
     * @param document 
     */
    public void print(Document document){

        String s = document.asXML();
        System.out.println(s);

    }

上面代码创建内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<service><!--这是一个service-->
    <head />
    <body>
        <name member="false"><!--借书人-->luck</name>
        <books>
            <book>
                <title>dom4j tutorials</title>
            </book>
        </books>
    </body>
</service>

读取文件

    /**
     * 读取xml文件
     * @param path 
     * @return
     * @throws DocumentException
     */
    private Document parse(String path) throws DocumentException {
        SAXReader reader = new SAXReader();
        return reader.read(new File(path));
    }

    /**
     * 读取 所有的book标签值
     * @param document 
     */
    private void readXML(Document document){
        List<Node> nodes = document.selectNodes("//book");
        for (Node node : nodes){
            Element ele = (Element) node;
            Element title = ele.element("title");
            System.out.println(title.getText());
        }
    }

修改xml

  1. 读取xml

  2. 找到需要修改的结点(元素)

  3. 调用各个对象的方法

    类型方法
    Documentremove 移除子元素
    Elementvoid setText(String var1) 设置文本
    remove 移除子元素
    AttributesetValue 设置属性值
  4. 保存 Document 对象

总结

掌握以上 dom4j 的基本概念和常用操作方法,可以读取一个标准xml的数据,以便于数据转换与存储。

参考文献

  1. dom4j.github.io/