xml-dom4j解析

1. sax的解析原理:事件驱动

javax.xml.parse包里面

  • SAXparse
    此类实例可以从SAXParerFactory.newSAXParser()方法获得
    parse(File f,DefaultHandle dh)//第一个参数xml路径,第二个参数事件处理器
    SAXParserFactory//实例newInstance()方法得到
    schema解析原理

2. 使用jaxp的sax方式解析xml

sax方式不能实现增删改的操作,只能做查询的操作

  • 打印出整个文档
    执行parse方法,第一个参数xml路径,第二个参数是事件处理器
    创建一个类,继承时间处理的类,重写里面的三个方法
  • 获取到所有的name元素的值
    定义一个成员变量flag= false
    判断开始方法是否是name元素,如果是name元素,把flag的值设置成true
    如果flag的值是ture,在characters方法中打印内容
    当执行到结束方法的的时候,把flag的值设置成false
  • **获取第一个name元素的值
    定义一个成员变量idx=1
    在结束方法的时候,idx+1
    想要打印出第一个name元素的值,在characters方法里面判断,flag==true&&id==1,再打印内容

3. 使用dom4j解析xml

dom4j,是一个组织,针对xml解析,提供解析器dom4j
dom4j不是javase的一部分,想要使用第一步应该导入dom4j提供的jar包

  • 得到document
    SAXReader reader = new SAXReader();
    Document doucment = reader.red(url);
  • document 的父接口是Node如果在document中找不到想要的方法,在Node里面找
  • document里面的 getRootElement():获取根节点返回的是Element
  • Element也是一个接口,父接口是Node
    Element和Node里面的方法
    getParent():获取父节点
    addElement():添加标签

4. 使用dom4j查询xml

<?xml version="1.0" encoding="UTF-8"?>
<person>
<p1>
  <name>zhangsan</name>
  <age>20</age>
</p1>
<p1>
  <name>lisi</name>
  <age>30</age>
</p1>
</person>

查询所有name元素里面的值

  1. 创建解析器
  2. 得到doucment
  3. 得到根节点getRootElement()
  4. 得到所有的p1元素
    element(qname)表示获取标签下面的第一个子标签。qname:标签的名称
    elements(qname)表示标签下面是这个名称的所有子标签(一层)
    elements():获取标签下面的所有一层子标签
  5. 得到name
  6. 得到name里面的值

得到第二个name里面的值

  1. 创建解析器
    SAXReader saxReader = new SAXReader();
  2. 得到document
    Document document - saxReader.read("src/p1.xml");
  3. 得到根节点
    Element root = document.getRootElement();
  4. 得到所有的p1
    List<Element> list = root.elements("p1");
  5. 得到第二个p1list集合下标cong0开始
    Element p2 = list.get(1);
  6. 得到p1下面的name
    Element name2 = p2.element("name");
  7. 得到name里面的值
    String s2 = name2.getText();
    System.out.println(s2);

5.在特定位置添加元素

在第一个p1下面的age标签之前添加<school>exit</school>
步骤:

  1. 创建解析器
  2. 得到document
  3. 得到根节点
  4. 获取到第一个p1
  5. 获取p1下面的所有元素element()方法返回的是list集合
    使用list里面的方法,在特定的位置添加元素
    首先创建元素,在元素下面创建文本
    使用DocumentHelper类方法createElement创建标签
    把文本添加到标签下面使用setText(“文本内容”)方法
    list集合里面的add(int index,E element)
    的一个参数是 位置下标,从0开始第二个参数是要添加的元素
    6.回写xml
package day6dom4jadd;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

import java.io.FileOutputStream;
import java.util.List;

public class add {
   public static void main(String[] args) throws Exception {
       add();
   }

   public static void add() throws Exception {
       //创建解析器
       SAXReader saxReader = new SAXReader();
       //得到document
       Document document = saxReader.read("src/day6dom4jadd/person.xml");
       //得到跟节点
       Element rootElement = document.getRootElement();
       //获取第一个p1
       Element p1 = rootElement.element("p1");
       //获取p1下面的所有的元素
       List<Element> elements = p1.elements();
       //创建元素使用
       Element school = DocumentHelper.createElement("school");
       //在school下创建文本
       school.setText("exit");
       //在特定位置添加
       elements.add(1, school);
       //回写xml
       OutputFormat format = OutputFormat.createPrettyPrint();
       XMLWriter xmlWriter = new XMLWriter(new FileOutputStream("src/day6dom4jadd/person.xml"), format);
       xmlWriter.write(document);
       xmlWriter.close();
   }

}

实现封装

package day6dom4jadd;

import org.dom4j.Document;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

import java.io.FileOutputStream;

public class Dom4jUtils {
    public static final String PATH = "src/day6dom4jadd/person.xml";
    public static Document getDocument(String path) {
        try{
            //创建解析器
            SAXReader reader = new SAXReader();
            //得到document
            Document document = reader.read(path);
            return document;
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }
    //回写方法
    public static  void xmlWriters(String path,Document document){
        try {
            OutputFormat format = OutputFormat.createPrettyPrint();
            XMLWriter xmlWriter = new XMLWriter(new FileOutputStream(path),format);
            xmlWriter.write(document);
            xmlWriter.close();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
package day6dom4jadd;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

import java.io.FileOutputStream;
import java.util.List;
public class add {
    public static void main(String[] args) throws Exception {
        add();
    }

    public static void add() throws Exception {
        //创建解析器
       // SAXReader saxReader = new SAXReader();
        //得到document
//        Document document = saxReader.read("src/day6dom4jadd/person.xml");
        //方法的封装
        Document document = Dom4jUtils.getDocument(Dom4jUtils.PATH);
        //得到跟节点
        Element rootElement = document.getRootElement();
        //获取第一个p1
        Element p1 = rootElement.element("p1");
        //获取p1下面的所有的元素
        List<Element> elements = p1.elements();
        //创建元素使用
        Element school = DocumentHelper.createElement("school");
        //在school下创建文本
        school.setText("exat");
        //在特定位置添加
        elements.add(1, school);
        //回写xml
       /* OutputFormat format = OutputFormat.createPrettyPrint();
        XMLWriter xmlWriter = new XMLWriter(new FileOutputStream("src/day6dom4jadd/person.xml"), format);
        xmlWriter.write(document);
        xmlWriter.close();*/
       //回写方法的封装
        Dom4jUtils.xmlWriters(Dom4jUtils.PATH,document);
    }

}

把document的操作和回写xml进行封装方法
也可以吧传递的文件路径,封装给一个常量
好处:可以提高代码的开发速度,可以提高代码的可维护性


6.使用dom4j实现与元素的修改

修改第一个p1下面的age元素的值<age>300</age>

public static void modifyAge()throws Exception{
        //得到document
        Document document = Dom4jUtils.getDocument(Dom4jUtils.PATH);
        //得到第一个根节点
        Element rootElement = document.getRootElement();
        //得到p1
        Element p1 = rootElement.element("p1");
        //得到p1下面的age
        Element age = p1.element("age");
        //修改age的值
        age.setText("300");
        //回写xml
        Dom4jUtils.xmlWriters(Dom4jUtils.PATH,document);
    }

7. 使用dom4j实现与元素的删除

//删除节点
    public static void del(){
        //得到document
         Document document = Dom4jUtils.getDocument(Dom4jUtils.PATH);
        //得到根节点
        Element rootElement = document.getRootElement();
        //得到p1元素
        Element p1 = rootElement.element("p1");
        //得到p1下面的school标签
        Element school = p1.element("school");
        //删除shcool,通过父节点删除,获得父节点的方法:sch.getParent();//获得school的父节点p1
        p1.remove(school);
        //回写xml
        Dom4jUtils.xmlWriters(Dom4jUtils.PATH,document);
    }

8.使用dom4j获取属性值的方法

查看第一个p1里面的属性值

//查看属性的值
    public static void getValues() throws Exception {
        //得到document
        Document document = Dom4jUtils.getDocument(Dom4jUtils.PATH);
        //得到根节点
        Element rootElement = document.getRootElement();
        //得到p1元素
        Element p1 = rootElement.element("p1");
        String id1 = p1.attributeValue("id1");
        System.out.println(id1);
    }

attributeValue()获取属性的值


9.使用dom4j支持xpath

可以直接获取某个元素

  • 形式:
    /AAA/DDD/BBB:表示一层一层的,AAA下面的DDD下面的BBB
    //BBB 表示和这个名称相同的都得到
    /*:所有元素
    BBB[1]:表示第一个BBB元素
    BBB[last()]:表示最后一个BBB元素
    //BBB[@id]:表示BBB元素上有id属性都可以得到

  • 在dom4j中提供了两个方法,用来支持xpath
    selectNodes("xpath表达式")获得多个节点
    selectSingleNode("xpath表达式")后的一个节点

使用xpath实现:查询xml中所有name元素的值

  1. 得到document
  2. 直接使用selectNodes("//name")方法得到所有的name元素
package day6xpath;

import day6dom4jadd.Dom4jUtils;
import org.dom4j.Document;
import org.dom4j.Node;

import java.util.List;

public class xpath {
    public static void main(String[] args) {
        test();
    }

    public static void test() {
        Document document = Dom4jUtils.getDocument(Dom4jUtils.PATH);
        List<Node> list = document.selectNodes("//name");
        for (Node node : list) {
            //node是每个name元素
            //得到name元素里面的值
            String s = node.getText();
            System.out.println(s);
        }
    }
}
  • 使用xpath实现:获取第一个p1下面的name的值
package day6xpath;

import day6dom4jadd.Dom4jUtils;
import org.dom4j.Document;
import org.dom4j.Node;

public class xpath2 {
    public static void main(String[] args) throws Exception {
        //使用xpath实现:获取第一个p1下面的name的值
        test2();
    }
    public static void test2()throws Exception{
        //得到document
        Document document = Dom4jUtils.getDocument(Dom4jUtils.PATH);
        //直接使用selectSingleNode方法
        Node name1 = document.selectSingleNode("//p1[@id1='aaa']/name");
        //得到name里面的值
        String s1 = name1.getText();
        System.out.println(s1);

    }
}

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

推荐阅读更多精彩内容

  • 1. XML总结 1.1. XML简介 XML : 可扩展的标记语言。(和HTML非常类似的) 可扩展的。 自定义...
    Ethan_Walker阅读 3,037评论 0 12
  • day5 一、表单提交方式 1.使用submit提交 2.使用button提交表单 3.使用超链接提交 4.onc...
    mwj610阅读 411评论 0 0
  • 1.schema 约束 1.dtd 语法: 2.schema符合 xml 的语法,xml 语句3.一个 xml 中...
    定格r阅读 370评论 0 0
  • 第3章 基本概念 3.1 语法 3.2 关键字和保留字 3.3 变量 3.4 数据类型 5种简单数据类型:Unde...
    RickCole阅读 5,128评论 0 21
  • 隔世低吟你的诗 文/苍穹残月 梦里的纯白色 开在了琥珀般的月牙上 我驾着前往金陵的彩云 客栈的酒旗随风轻摇 我们在...
    苍穹残月阅读 132评论 0 0