Java解析xml文件dom4j篇

Java解析xml文件dom4j篇,第1张

DOM4J解析XML文件

dom4j是一个Java的XML API,是jdom的升级品,用来读写XML文件的。另外对比其他API读写XML文件,dom4j是一个十分优秀的JavaXML API,具有性能优异、功能强大和极其易使用的特点,它的性能超过sun公司官方的dom技术!如今越来越多的Java软件、Java框架都在使用dom4j来读写XML文件,例如Sun公司的JAXM、Hinernate等都是使用dom4j来读取并解析配置文件。

作为一名Java开发者,非常推荐去学习XML文件的解析方式,无论是深入理解框架底层的解析方式(你就知道怎么编写配置文件了,例如Spring底层的解析方式)、还是在工作中自定义一些特定的配置文件(例如SQL映射文件、数据映射文件等)非常的灵活与实用!

当然这里主要是以解析xml配置文件的方式去介绍dom4j的在实际项目开发中运用方式,更多写的 *** 作可以自行学习。另外如果单纯的只是解析配置文件非常推荐使用dom4j,性能完全够用!但是要解析有大量数据的xml文件时,就要考虑内存溢出问题,此时dom4j就不怎么合适了,要用SAX事件驱动解析方式(采用事件驱动模式,对内存消耗较小适用于处理拥有大量数据的xml文件),这种解析方式在另外一篇博客有介绍。

jar获取 / 引入方式:

1、maven


<dependency>
    <groupId>org.dom4jgroupId>
    <artifactId>dom4jartifactId>
    <version>2.1.1version>
dependency>

<dependency>
    <groupId>jaxengroupId>
    <artifactId>jaxenartifactId>
    <version>1.1.1version>
dependency>

2、gradle

// https://mvnrepository.com/artifact/org.dom4j/dom4j
implementation group: 'org.dom4j', name: 'dom4j', version: '2.1.1'

// https://mvnrepository.com/artifact/jaxen/jaxen
implementation group: 'jaxen', name: 'jaxen', version: '1.1.1'

引入jaxen的依赖是因为使用dom4j的xpath查询xml节点时,需要jaxen提供支持!否则会抛会java.lang.ClassNotFoundException: org.jaxen.JaxenException的异常。

这里为什么要提一下gradle呢?Gradle抛弃了基于XML的各种繁琐配置,确实更优秀、更简洁,并且SpringBoot 3.0默认的版本管理器也换成Gradle了(但是国内Gradle从中央仓库下载依赖是真的慢),未来可能会成为趋势!

1、环境准备 1.1、常用类及方法介绍

DOM4J常用的类

类名用途
Attribute定义了 XML 的属性。
Branch指能够包含子节点的节点。如XML元素(Element)和文档(Docuemnts)定义了一个公共的行为
CDATA定义了 XML 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 表达式

Element类常见的方法。我们解析XML文件最终都会把标签对转成Element节点对象,去读取节点属性与节点元素所含有的text内容,所以这个类非常重要。

方法名含义
getQName()元素的QName对象
getNamespace()元素所属的Namespace对象
getNamespacePrefix()元素所属的Namespace对象的prefix
getNamespaceURI()元素所属的Namespace对象的URI
getName()元素的local name
getQualifiedName()元素的qualified name
getText()元素所含有的text内容,如果内容为空则返回一个空字符串而不是null
getTextTrim()元素所含有的text内容,其中连续的空格被转化为单个空格,该方法不会返回null
attributeIterator()元素属性的iterator,其中每个元素都是Attribute对象
attributeValue()元素的某个指定属性所含的值
elementIterator()元素的子元素的iterator,其中每个元素都是Element对象
element()元素的某个指定(qualified name或者local name)的子元素
elementText()元素的某个指定(qualified name或者local name)的子元素中的text信息
getParent元素的父元素
getPath()元素的XPath表达式,其中父元素的qualified name和子元素的qualified name之间使用"/"分隔
isTextOnly()是否该元素只含有text或是空元素
1.2、项目环境搭建

这里主要已Gradle来构建一个测试工程,当然也可以使用Maven来构建,没有任何区别的除了引入jar包的方式。例如项目结构与引入的GAV坐标如下:

暂时先引入这几个依赖坐标,后面用到什么添加什么即可。搭建好基础环境后,我们用一个完整的项目功能案例,来体验dom4j的解析过程,与在项目上的使用方式。

2、功能实现 2.1、功能简要说明

我们要完成的项目功能为,基于XML配置文件完成Excel数据的导入与导出功能(从前端传入Excel文件完成数据入库或导出表数据至Excel文件)。这个功能看似简单其实做起来会涉及到非常多的东西,例如

1、持久层框架JPA集成(数据库我们采用Oracle,当然也可以使用MyBatis-Plus+MySQL看自己的选择)

2、设计XML映射 / 配置文件(实体、Excel标题、数据库表字段的映射关系。通过XML文件实现)最终Excel数据通过xml配置文件获取需要保存到数据库的实体集合。

3、XML文件的解析方式(使用DOM4J解析)

4、通用工具类的封装(通用的XML解析器)

5、解析Excel文件数据(通过Apache POI解析)

等等

重要的是学会一种思想,自定义配置文件,自己去解析!去满足特定的场景,例如我们想通过JPA执行复杂原生SQL,或完成自己的动态SQL,就可以把SQL语句写在特定的XML标签上,自己去解析与获取。在来说动态SQL,学会XML文件解析后,完全可以实现MyBatis的动态SQL功能,只需要设计特定的标签,SQL传参的时候判断有没有这个参数,有则拼接上SQL,没有则不拼接SQL。

2.2、SpringBoot集成JPA

关于更多的JPA知识这里就不多说了。

1、引入相关依赖(JPA/数据库驱动),注意最后两个是最新引入的。

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.12';
    // https://mvnrepository.com/artifact/org.dom4j/dom4j
    implementation group: 'org.dom4j', name: 'dom4j', version: '2.1.1';
    // https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web
    implementation group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '2.5.5';
    // https://mvnrepository.com/artifact/org.projectlombok/lombok
    compileOnly group: 'org.projectlombok', name: 'lombok', version: '1.18.20';
    // https://mvnrepository.com/artifact/com.alibaba/fastjson
    implementation group: 'com.alibaba', name: 'fastjson', version: '1.2.75';
    // https://mvnrepository.com/artifact/jaxen/jaxen
    implementation group: 'jaxen', name: 'jaxen', version: '1.1.1';

    // https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-jpa
    implementation group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa';
    // https://mvnrepository.com/artifact/com.oracle.database.jdbc/ojdbc6
    implementation group: 'com.oracle.database.jdbc', name: 'ojdbc6', version: '11.2.0.4';
}

2、编写application.properties文件(数据库的连接信息的)

server.port=8080
spring.application.name=example
spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver
spring.datasource.url=jdbc:oracle:thin:@122.41.571.179:1521:helowin
spring.datasource.username=LN
spring.datasource.password=LN
spring.jpa.show-sql=true

3、编写实体类(注意注解的使用方式,SQL脚本在后面)

/**
 * @description: UserEntity
 * @date: 2022/3/13 11:00
 */
@Entity
@Table(name = "LN_USER", schema = "LN") // schema属性在ORACLE数据库中填用户ID
@JsonIgnoreProperties(value = {"hibernateLazyInitializer", "handler"})
public class UserEntity implements Serializable {
    private static final long serialVersionUID = 7521045049709813121L;
    private Integer id;
    private String username;
    private String password;

    @Id
    @Column(name = "ID", unique = true, nullable = false)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "LN_USER_ID")
    @SequenceGenerator(name = "LN_USER_ID", schema = "LN", sequenceName = "S_LN_USER", allocationSize = 1)
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    @Column(name = "USERNAME")
    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    @Column(name = "PASSWORD")
    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

SQL脚本

/* 创建表空间 */
CREATE TABLESPACE LN_TEST
DATAFILE '/home/oracle/app/oracle/oradata/helowin/ln_test.dbf'
SIZE 100M
AUTOEXTEND ON
NEXT 10M

/* 给用户重新指定表空间(因为LN这个用户我们之前就创建好了) */
ALTER USER LN DEFAULT TABLESPACE LN_TEST;

/* 创建序列 */
CREATE SEQUENCE "LN"."S_LN_USER" MINVALUE 1 MAXVALUE 99999 INCREMENT BY 1 CACHE 20;

/* 最后在创建表 */
CREATE TABLE "LN"."LN_USER" (
  "ID" NUMBER(10,0) NOT NULL,
  "USERNAME" VARCHAR2(255 BYTE),
  "PASSWORD" VARCHAR2(255 BYTE),
  CONSTRAINT "SYS_C0011150" PRIMARY KEY ("ID"),
  CONSTRAINT "SYS_C0011149" CHECK ("ID" IS NOT NULL) NOT DEFERRABLE INITIALLY IMMEDIATE NORELY VALIDATE
)
TABLESPACE "LN_TEST"
LOGGING
NOCOMPRESS
PCTFREE 10
INITRANS 1
STORAGE (
  BUFFER_POOL DEFAULT
)
PARALLEL 1
NOCACHE
DISABLE ROW MOVEMENT

4、编写Dao接口,需要继承JPA提供的JpaRepository接口

/**
 * @description: UserDao
 * @date: 2022/4/26 21:58
 */
public interface UserDao extends JpaRepository<UserEntity, Integer> {
}

5、编写测试方法,数据库访问是否正常

/**
 * @description:
 * @date: 2022/4/26 22:15
 */
@RestController
@RequestMapping(value = "/user")
public class UserController {
    @Autowired
    private UserDao userDao;
    @RequestMapping(value = "/getList", method = RequestMethod.GET)
    public R getUserList() {
        return R.ok().put("data", userDao.findAll());
    }
}

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/740418.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-28
下一篇 2022-04-28

发表评论

登录后才能评论

评论列表(0条)

保存