XML解析——DOM4J

DOM4J

Dom4j是一个简单、灵活的开源库,dom4j使用接口和抽象基类,Dom4j的API相对要复杂一些但比JDOM更好的灵活性。 Dom4j是完美支持Xpath,具有性能优异、功能强大和极易使用的特点。采用的Dom4j需下载dom4j相应的jar文件


Document对象

DOM4J中,获得Document对象的方式有三种:

  • 读取XML文件,获得document对象
    SAXReader reader = new SAXReader();
    Document document = reader.read(url);
  • 解析XML形式的文本,得到document对象.
    String text = "<members></members>";
    Document document = DocumentHelper.parseText(text);
  • 主动创建document对象.
    Document document = DocumentHelper.createDocument(); //创建根节点
    Element root = document.addElement("members");

节点对象的增删查改

  • 获取文档的根节点.
    Element root = document.getRootElement();
  • 取得某个节点的子节点.
    Element element=node.element(“书名");
    element.element("售价");
  • 取得节点的文字
    String text=node.getText();
  • 取得某节点下所有名为“member”的子节点
    List nodes = rootElm.elements("member");
  • 在某节点下添加子节点.
    Element ageElm = newMemberElm.addElement("age");
  • 设置节点文字.
    element.setText("29");
  • 删除某节点.
    parentElm.remove(childElm);//childElm是待删除的节点,parentElm是其父节
  • 添加一个CDATA节点.
    Element contentElm = infoElm.addElement("content");
    contentElm.addCDATA(diary.getContent());

节点对象属性

  • 取得某节点下的某属性
    Element root=document.getRootElement(); //属性名name
    Attribute attribute=root.attribute("size");
  • 取得属性的文字
    String text=attribute.getText();
  • 删除某属性
    Attribute attribute=root.attribute("size");
    root.remove(attribute);
  • 获取某节点的所有属性
    Element root=document.getRootElement();
    List attributes =root.attributes();
  • 设置某节点的属性和文字.
    newMemberElm.addAttribute("name", "sitinspring");
  • 设置属性的文字
    Attribute attribute=root.attribute("name");
    attribute.setText("sitinspring");

将文档写入XML文件

  • 文档中全为英文,不设置编码,直接写入的形式.
    XMLWriter writer = new XMLWriter(new FileWriter("output.xml"));
    writer.write(document);
    writer.close();
  • 文档中含有中文,设置编码格式写入的形式.
    OutputFormat format = OutputFormat.createPrettyPrint();// 指定XML编码
    format.setEncoding("GBK");
    XMLWriter writer = new XMLWriter(new FileOutputStream("output.xml"),format);
    writer.write(document);
    writer.close();

在指定位置插入节点

  • 得到插入位置的节点列表(list)
  • 调用list.add(index,elemnent),由index决定element的插入位置。
    Element元素可以通过DocumentHelper对象得到
    Element aaa = DocumentHelper.createElement("aaa");
    aaa.setText("aaa");
    List list = root.element("书").elements();
    list.add(1, aaa);//更新document

DOM4J解析编程

xml文档
<?xml version="1.0" encoding="utf-8"?>
 <书架>
    <书>
        <书名>浪潮之巅</书名>
        <作者>吴军</作者>
        <作者>李开复</作者>
        <售价>50</售价>
        <个人信息><age>50</age></个人信息>
    </书>
    <书>
        <书名>数学之美</书名>
        <作者 title='ADS'>陆奇</作者>
        <售价>29</售价>
        <个人信息><age>50</age></个人信息>
    </书>
</书架>




解析代码并打印输出(不使用xpath)

//为了使代码结构清晰 异常全部thorws
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

public class Dom4jDemo2
{
    public static void main(String[] args) throws DocumentException, IOException
    {
        // 获取document对象
        SAXReader reader = new SAXReader();
        Document document = reader.read(new File("book.xml"));

        // 1.调用getRootElement()获取文档的根节点.
        Element rootElement = document.getRootElement();

        // 调用element()第一本书 
        /*Element接口表示 HTML或 XML 文档中的一个元素。元素可能有与它们相关的属性;
        Element接口继承自 Node,方法更丰富,返回一个集合*/
        Element firstbook = rootElement.element("书");

        // 2、 elements()获取此元素节点的所有子节点
        List<Element> elements = firstbook.elements();
        //遍历集合中的元素子节点,打印所有元素子节点
        for (Element element2 : elements)
        {
            String text = element2.getText();
            System.out.println(element2.getName() + text);
        }

        // 取得某节点下所有名为“作者”的子节点,并打印出来 .
        List elements2 = firstbook.elements("作者");
        for (Object object : elements2)
        {//遍历子节点获取作者标签内的  文本内容
            Element element2 = (Element) object;
            System.out.println(element2.getText());
        }

        // 3、elements() element()修改某个元素节点的主体内容 修改第二本书的作者 为 李开复
        Element secondBook = (Element) rootElement.elements("书").get(1);
        Element secondBookAuthor = secondBook.element("作者");
        secondBookAuthor.setText("Kaifu Lee");

        System.out.println(secondBookAuthor.getText());

        // 4、addElement()向指定元素节点中增加子元素节点 第一本书增加ISBN 
        Element addElement = firstbook.addElement("ISBN");
        addElement.setText("987465498748");

        // 5、向指定元素节点上增加同级元素节点
        // 增加一本书 找到父节点 书架
        Element addElement2 = rootElement.addElement("书");
           //增加书名节点
        Element bookname = addElement2.addElement("书名");
        bookname.setText("解忧杂货铺");
         
        Element bookauthor = addElement2.addElement("作者");
        bookauthor.setText("东野圭吾");

        Element bookprice = addElement2.addElement("售价");
        bookprice.setText("2RMB");
               //增加售价的属性
        bookprice.addAttribute("where", "amazon");

        // 6、删除指定元素节点
        Element element = firstbook.element("个人信息");
        firstbook.remove(element);

        // 把内存中的dom树 写回到一个xml文件
        OutputFormat format = OutputFormat.createPrettyPrint();
        // 指定XML编码 输出到output.xml
        format.setEncoding("GBK");
        XMLWriter writer;
        writer = new XMLWriter(new FileOutputStream("output.xml"), format);
        writer.write(document);
        writer.close(); 
    }
}
控制台输出
书名浪潮之巅
作者吴军
作者李开复
售价50
个人信息
吴军
李开复
Kaifu Lee


解析代码并打印输出(使用xpath)

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

//使用Xpath的情况是
public class Dom4jDemo
{
    public static void main(String[] args) throws DocumentException, IOException, IOException
    {
        //获取Document对象
        SAXReader reader = new SAXReader();
        Document document = reader.read(new File("book.xml"));

        // 1.获取文档的根节点.
        // 第一本书 /书架/书[1]
        List selectNodes = document.selectNodes("/书架/书[1]");
        Element object2 = (Element) selectNodes.get(0);

        // 2、打印某节点的所有元素子节点
        List firstbookchildren = document.selectNodes("/书架/书[1]/*");
        for (Object object : firstbookchildren)
        {
            Element element = (Element) object;
            System.out.println(element.getName() + element.getText());

        }
        // 取得某节点下所有名为“作者”的子节点,并打印出来 
        List selectNodes2 = document.selectNodes("//作者");
        for (Object object : selectNodes2)
        {
            Element element2 = (Element) object;
            System.out.println(element2.getText());
        }
        // 3、修改某个元素节点的主体内容 修改第二本书的作者 为 李开复
        Element selectNodes3 = (Element) document
                .selectSingleNode("/书架/书[2]/作者");
        selectNodes3.setText("Owen");

        // 4、向指定元素节点上增加同级元素节点
        // 增加一本书 找到父节点 书架

        Element addElement2 = document.getRootElement().addElement("书");

        Element bookname = addElement2.addElement("书名");
        bookname.setText("解忧杂货铺");

        Element bookauthor = addElement2.addElement("作者");
        bookauthor.setText("东野圭吾");

        Element bookprice = addElement2.addElement("售价");
        bookprice.setText("2RMB");

        bookprice.addAttribute("where", "amazon");

        // 把内存中的dom树 写回到一个xml文件
        OutputFormat format = OutputFormat.createPrettyPrint();
                
        //// 指定XML编码 写出到指定文件           
        format.setEncoding("GBK");
        XMLWriter writer;
        writer = new XMLWriter(new FileOutputStream("output.xml"), format);
        writer.write(document);
        writer.close();
    }
}

控制台输出
书名浪潮之巅
作者吴军
作者李开复
售价50
个人信息
吴军
李开复
陆奇


OUTPUT.xml

<?xml version="1.0" encoding="GBK"?>
<书架> 
  <书> 
    <书名>浪潮之巅</书名>  
    <作者>吴军</作者>  
    <作者>李开复</作者>  
    <售价>50</售价>  
    <个人信息>
      <age>50</age>
    </个人信息> 
  </书>  
  <书> 
    <书名>数学之美</书名>  
    <作者 title="ADS">Owen</作者>  
    <售价>29</售价>  
    <个人信息>
      <age>50</age>
    </个人信息> 
  </书>  
  <书>
    <书名>解忧杂货铺</书名>
    <作者>东野圭吾</作者>
    <售价 where="amazon">2RMB</售价>
  </书>
</书架>

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,179评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,229评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,032评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,533评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,531评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,539评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,916评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,813评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,568评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,654评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,354评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,937评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,918评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,152评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,852评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,378评论 2 342

推荐阅读更多精彩内容