XML解析---DOM4J,使用DOM4J解析Mybatis配置文件和映射文件

1、dom4j简介

dom4j是阿帕奇出品的一个开源 XML 解析包,是一个简单、灵活的开源库,用来读写XML文件的。dom4j使用接口和抽象基类,是jdom的升级品,dom4j的API相对要复杂一些但比jdom更好的灵活性。
Dom4j是完美支持Xpath,具有性能优异、功能强大和极易使用的特点。
XPath 是一门在 XML 文档中查找信息的语言。
Xpath包下载地址:http://www.cafeconleche.org/jaxen
Xpath maven发送导入依赖:

<dependency>
    <groupId>org.dom4j</groupId>
    <artifactId>dom4j</artifactId>
    <version>版本号</version>
</dependency>

dom4j包下载地址:http://dom4j.github.io/
Xpath maven方式导入依赖:

<dependency>
    <groupId>jaxen</groupId>
    <artifactId>jaxen</artifactId>
    <version>版本号</version>
</dependency>

2、XPath基本语法

选取节点语法

XPath 使用路径表达式在 XML 文档中选取节点。

表达式描述
标签名选取此标签的所有子节点。
/从根节点选取(取子节点)。
//从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置(取子孙节点)。
.选取当前节点。
选取当前节点的父节点。
@选取属性。

谓语语法

谓语用来查找某个特定的节点或者包含某个指定的值的节点。

谓语被嵌在方括号[ ]中。

路径表达式结果
/标签1/标签2[数字]选取属于标签1 子元素的第‘数字’个 标签2元素。类似数组
/标签1/标签2[last()]选取属于 标签1 子元素的最后一个 标签2 元素。
/标签1/标签2[position()< 3]选取最前面的两个属于 标签1 元素的子元素的 标签2 元素。
//标签[@属性名]选取所有拥有名为 ‘属性名’ 的属性的 标签 元素。
//标签[@属性名=‘属性值’]选取所有 标签 元素,且这些元素拥有值为 ‘属性名=‘属性值’。

选取未知节点语法

XPath 通配符可用来选取未知的 XML 元素。

通配符描述
*匹配任何元素节点。
@*匹配任何属性节点。
node()匹配任何类型的节点。

选取若干路径语法

通过在路径表达式中使用"|"运算符,您可以选取若干个路径。
例如
//标签1 | //标签2
选取文档中的所有 标签1 和 标签2 元素。

3、DOM4J接口

接口功能
Attribute定义了 XML 的属性。
BranchBranch接口定义了节点的常见行为,这些节点可以包含子节点(内容),例如XML元素和文档。
CDATA定义了 XML CDATA 区域,指CDATA 部分中的所有内容都会被解析器忽略。
CharacterData是一个标识接口,标识基于字符的节点。如CDATA,Comment, Text.
Comment定义了 XML 注释的行为
Document定义了XML 文档
DocumentType定义 XML DOCTYPE 声明
Element定义XML 元素
ElementHandler定义了Element 对象的处理器
ElementPath被 ElementHandler 使用,用于取得当前正在处理的路径层次信息
Entity定义 XML entity
Node为dom4j中所有的XML节点定义了多态行为
NodeFilter定义了在dom4j 节点中产生的一个滤镜或谓词的行为(predicate)
ProcessingInstruction定义 XML 处理指令
Text定义 XML 文本节点
Visitor用于实现 Visitor模式
XPath在分析一个字符串后会提供一个 XPath 表达式

接口之间的继承关系如下:

interface java.lang.Cloneable

    interface org.dom4j.Node

           interface org.dom4j.Attribute

           interface org.dom4j.Branch

                  interface org.dom4j.Document

                  interface org.dom4j.Element

           interface org.dom4j.CharacterData

                  interface org.dom4j.CDATA

                  interface org.dom4j.Comment

                  interface org.dom4j.Text

           interface org.dom4j.DocumentType

           interface org.dom4j.Entity

           interface org.dom4j.ProcessingInstruction

4、使用DOM4J解析Mybatis配置文件

首先需要导入依赖

	<!--dem4j依赖-->
    <dependency>
      <groupId>org.dom4j</groupId>
      <artifactId>dom4j</artifactId>
      <version>2.1.3</version>
    </dependency>
    <!--jaxen依赖-->
    <dependency>
      <groupId>jaxen</groupId>
      <artifactId>jaxen</artifactId>
      <version>1.2.0</version>
    </dependency>
    <!--junit依赖-->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13.2</version>
      <scope>test</scope>
    </dependency>

配置文件如下

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <!--mysql数据库连接信息-->
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mydbtest"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!--指定Mapper.xml文件的路径,resource是在类的根资源路径下查找-->
        <mapper resource="DeptMapper.xml"/>
        <mapper resource="CarMapper2.xml"/>
        <mapper resource="CarMapper3.xml"/>
    </mappers>
</configuration>

解析步骤
1.使用Dom4j创建reader对象
2.通过类加载器获取Myabtis的配置文件输入流
3.读XML文件,返回一个文档对象document
4.对标签进行处理
4.1获取默认的环境,因为将来有可能配置多个环境
(1)获取environments的default的值
(2)通过defalt获取默认environment
4.2处理默认环境的配置
(1)获取事务管理器类型
(2)获取数据源类型
(3)处理dataSource下的所有子节点
5.获取所有的Mapper标签,进行处理

@Test
    public void testMybatisConfigXML() throws DocumentException {
        //1.使用Dom4j创建reader对象
        SAXReader reader = new SAXReader();
        //2.通过类加载器获取Myabtis的配置文件输入流
        InputStream config_stream = ClassLoader.getSystemClassLoader().getResourceAsStream("mybatis-config.xml");
        //3.读XML文件,返回一个文档对象document
        Document document = reader.read(config_stream);
        //4.对标签进行处理
        //4.1获取默认的环境,因为将来有可能配置多个环境
        //(1)获取environments的default的值
        //xpath是做标签匹配路径,能够让我们快捷定位XML文件的标签
        String xpath = "/configuration/environments";//这个意思是从根开始找标签configuration,然后找environments
        //通过标签匹配路径获取节点,这样就获取到了environments这个节点,返回是Node,Element是Node的子类,方法更多,使用更方便
        Element environments = ((Element) document.selectSingleNode(xpath));
        //通过attributeValue获取default的值
        String defalt = environments.attributeValue("default");
        //(2)通过defalt获取默认environment
        //xpath是可以通过属性获取标签的,语法是  标签[@属性名=属性值]  
        xpath = "/configuration/environments/environment[@id='"+defalt+"']";
        Element environment = (Element) document.selectSingleNode(xpath);

        //4.2处理默认环境的配置
        //(1)获取事务管理器类型
        //获取environment下的transactionManager标签,element用来获取孩子节点
        Element transactionManager = environment.element("transactionManager");
        //获取事务管理器的类型
        String transactionType = transactionManager.attributeValue("type");
        System.out.println("事务管理器的类型:" + transactionType);
        //(2)获取数据源类型
        Element dataSource = (Element) environment.element("dataSource");
        String dataSourceType = dataSource.attributeValue("type");
        System.out.println("数据源类型:" + dataSourceType);
        //(3)处理dataSource下的所有子节点
        List<Element> propertys = dataSource.elements();
        propertys.forEach(propertysElt -> {
            String name = propertysElt.attributeValue("name");
            String value = propertysElt.attributeValue("value");
            //mybatis到时候会用map进行存取
            System.out.println(name + "=" + value);
        });
        //5.获取所有的Mapper标签,进行处理
        //不想从根路径下获取,想从某个标签的所有标签,xpath的语法是 “//标签”
        xpath = "//mapper";
        List<Node> mappers = document.selectNodes(xpath);
        mappers.forEach(mapper -> {
            Element mapperElt = (Element) mapper;
            String resource = mapperElt.attributeValue("resource");
            //到时候应该是动态解析这个资源文件
            System.out.println(resource);
        });
    }

结果
请添加图片描述

5、使用DOM4J解析映射文件

映射文件如下

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="dept">
    <!--id是这条语句的唯一标识。这个id就代表了这条SQL语句-->
    <insert id="insertDept">
        insert into t_mybatis
        value(#{deptno},#{dname},#{loc})
    </insert>
    <select id="selectById" resultType="com.pojo.Dept">
        select * from t_mybatis where deptno=#{deptno}
    </select>
</mapper>

解析步骤
1.使用Dom4j创建reader对象
2.通过类加载器获取Myabtis的配置文件输入流
3.读XML文件,返回一个文档对象document
4.对标签进行处理
(1)获取根标签的namespace
(2)获取mapper的所有子节点

@Test
    public void testSqlMapperXML() throws DocumentException {
        //1.使用Dom4j创建reader对象
        SAXReader reader = new SAXReader();
        //2.通过类加载器获取SqlMapper的配置文件输入流
        //mybatis是动态获取的,这里是测试写死
        InputStream SqlMapper_stream = ClassLoader.getSystemClassLoader().getResourceAsStream("DeptMapper.xml");
        //3.读XML文件,返回一个文档对象document
        Document document = reader.read(SqlMapper_stream);
        //4.对标签进行处理
        //(1)获取根标签的namespace
        String xpath = "/mapper";
        Element mapper = (Element) document.selectSingleNode(xpath);
        String namespace = mapper.attributeValue("namespace");
        System.out.println(namespace);
        //(2)获取mapper的所有子节点
        List<Element> elements = mapper.elements();
        elements.forEach(element -> {
            String id = element.attributeValue("id");
            String resultType = element.attributeValue("resultType");//没有这个属性会自动返回null
            String sql = element.getTextTrim();//表示获取标签内容,而且去除前后空白
            System.out.println(sql);
            //转换sql语句,使用正则表达式把#{}的内容替换成占位符?
            String newsql = sql.replaceAll("#\\{[0-9A-Za-z_$]*}", "?");
            System.out.println(newsql);
        });
    }

结果请添加图片描述

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

忆亦何为

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值