【Java Xml】Apache Commons Digester3解析

作者:Lucky_Turtle日期:2025/10/16

文章目录

  • 概述
  • 前期准备
  • 使用
    • 1、简单读取示例
    • 2、多个标签读取示例
  • 细节问题
    • addSetNext顺序
  • 参考

概述

官网
写入查看另一篇:https://blog.csdn.net/qq%5F45742250/article/details/153191615

前期准备

maven

1<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-digester3 -->
2<dependency>
3    <groupId>org.apache.commons</groupId>
4    <artifactId>commons-digester3</artifactId>
5		<version>3.2</version>
6</dependency>
7
8<dependency>
9    <groupId>org.projectlombok</groupId>
10    <artifactId>lombok</artifactId>
11    <version>1.18.36</version>
12</dependency>
13

使用

1、简单读取示例

test.xml

1<Book>
2    <Title>Java Programming</Title>
3    <Author>John Doe</Author>
4    <Price>39.99</Price>
5</Book>
6

Book.java

1public class Book {
2    private String title;
3    private String author;
4    private int price;
5
6    // getter和setter方法省略
7}
8

使用示例

1Digester digester = new Digester();
2// 当遇到<Book>标签时,创建一个Book类的实例
3digester.addObjectCreate("Book", Book.class);
4
5// 当遇到<Book>下的<Title>标签时,将其内容设置到Book实例的title属性上
6digester.addBeanPropertySetter("Book/Title", "title");
7
8// 对<Author>和<Price>标签做同样的操作
9digester.addBeanPropertySetter("Book/Author", "author");
10digester.addBeanPropertySetter("Book/Price", "price");
11
12// 文件路径
13String filePath = "demo/test.xml";
14
15// 存储文件内容
16StringBuilder content = new StringBuilder();
17
18try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
19    String line;
20    while ((line = br.readLine()) != null) {
21        content.append(line).append(System.lineSeparator()); // 拼接每行
22    }
23    System.out.println(content);  // 打印文件内容
24} catch (IOException e) {
25    e.printStackTrace();
26}
27

2、多个标签读取示例

library.xml

1<Library>
2    <Book>
3        <Title>Java编程指南</Title>
4        <Author>王五</Author>
5        <Price>88</Price>
6    </Book>
7    <Book>
8        <Title>高级Java技术</Title>
9        <Author>赵六</Author>
10        <Price>120</Price>
11    </Book>
12</Library>
13

Book.java

1public class Book {
2    private String title;
3    private String author;
4    private int price;
5
6    // getter和setter方法省略
7}
8

Library.java

1public class Library {
2    private List<Book> books = new ArrayList<>();
3
4    // getter、setter、toString方法省略
5    
6    // 添加书籍到书单中
7    public void addBook(Book book) {
8        books.add(book);
9    }
10}
11

使用示例

1Digester digester = new Digester();
2// 当遇到<Library>标签时,创建一个Book类的实例
3digester.addObjectCreate("Library", Library.class);
4
5digester.addObjectCreate("Library/Book", Book.class);
6digester.addBeanPropertySetter("Library/Book/Title", "title");
7digester.addBeanPropertySetter("Library/Book/Author", "author");
8digester.addBeanPropertySetter("Library/Book/Price", "price");
9// 将解析到的 Book 对象添加到 Library 的书单中(注意这里这个addSetNext,下文有解释,必须在已经添加号Library、Book类之后)
10digester.addSetNext("Library/Book", "addBook");
11
12// 文件路径
13String filePath = "demo/library.xml";
14
15// 存储文件内容
16StringBuilder content = new StringBuilder();
17
18try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
19    String line;
20    while ((line = br.readLine()) != null) {
21        content.append(line).append(System.lineSeparator()); // 拼接每行
22    }
23    System.out.println(content);  // 打印文件内容
24} catch (IOException e) {
25    e.printStackTrace();
26}
27
28try {
29    Library library = digester.parse(new StringReader(content.toString()));
30    // 这里的xmlString是包含上面XML内容的字符串
31
32    // 输出解析结果,检查是否正确
33    System.out.println("library: " + library.toString());
34} catch (IOException | SAXException e) {
35    e.printStackTrace();
36}
37

细节问题

addSetNext顺序

正确做法:

1Digester digester = new Digester();
2// 当遇到<Library>标签时,创建一个Book类的实例
3digester.addObjectCreate("Library", Library.class);
4
5digester.addObjectCreate("Library/Book", Book.class);
6digester.addBeanPropertySetter("Library/Book/Title", "title");
7digester.addBeanPropertySetter("Library/Book/Author", "author");
8digester.addBeanPropertySetter("Library/Book/Price", "price");
9// (注意这里)将解析到的 Book 对象添加到 Library 的书单中
10digester.addSetNext("Library/Book", "addBook");
11

错误做法:

1Digester digester = new Digester();
2// 当遇到<Library>标签时,创建一个Book类的实例
3digester.addObjectCreate("Library", Library.class);
4// (注意这里)将解析到的 Book 对象添加到 Library 的书单中
5digester.addSetNext("Library/Book", "addBook");
6
7digester.addObjectCreate("Library/Book", Book.class);
8digester.addBeanPropertySetter("Library/Book/Title", "title");
9digester.addBeanPropertySetter("Library/Book/Author", "author");
10digester.addBeanPropertySetter("Library/Book/Price", "price");
11

原因:

  1. addSetNext("Library/Book", "addBook") 被提前放置,这样在 Book 对象还没有创建时就试图将它添加到 Librarybooks 属性中。Book 对象尚未实例化,因此会引发错误或不正确的行为。
  2. addSetNext 需要确保在 Book 被创建之后才能执行,即 Book 对象已经存在,才能调用 LibraryaddBook 方法。

解决方案:
为了确保 Book 对象能够正确添加到 Library 中,应该遵循以下顺序:
3. 首先创建 Library 对象。
4. 然后创建 Book 对象,并为其设置属性。
5. 最后使用 addSetNext 将创建好的 Book 对象添加到 Library 中。

参考

https://segmentfault.com/a/1190000044528235
https://juejin.cn/post/7066826274836054023
https://www.oryoy.com/news/jie-mi-apache-chu-li-xml-de-du-xie-ji-qiao-qing-song-jia-yu-fu-za-shu-ju-jie-gou.html


【Java Xml】Apache Commons Digester3解析》 是转载文章,点击查看原文


相关推荐


elasticsearch-8.12.2集群部署
peng1792025/10/15

一:下载和解压JDK安装包 下载地址:https://mirrors.huaweicloud.com/openjdk/17/openjdk-17_linux-x64_bin.tar.gz 解压:tar -zxvf jdk-17_linux-x64_bin.tar.gz 二:配置JDK环境 编辑/etc/profile文件: vi /etc/profile    JAVA_HOME=/opt/jdk/jdk-17    PATH=$JAVA_HOME/bin:$PATH 保存后执行s


机器人控制基础:步进驱动器的选型总结
start_up_go2025/10/13

目录 一、选型核心维度:先匹配电机,再适配需求 1. 基础匹配:与步进电机参数严格兼容 2. 应用需求导向:确定驱动器性能与功能 3. 功能需求:按需选择保护与辅助功能 4. 环境适应性:匹配使用场景的物理条件 二、选型关键步骤:从参数到落地的 5 步流程 步骤 1:明确步进电机的核心参数 步骤 2:定义应用的核心需求 步骤 3:筛选驱动器的基础参数 步骤 4:验证功能与兼容性 步骤 5:预留余量,避免极限运行 三、选型注意事项:避开常见误区 四、典型场景选型示例


【k8s】基础概念+下载安装教程
_BugMan2025/10/12

目录 k8s提供的核心能力 1. 自动化运维与自愈能力 2. 服务的弹性伸缩 3. 服务发现与负载均衡 4. 发布与回滚 5. 配置与秘钥管理 组件 核心组件 概念组件 扩展组件 下载安装 测试 kubectl命令 k8s提供的核心能力 k8s可以理解为一个 1. 自动化运维与自愈能力 这是 K8S 最吸引人的能力之一。 自动重启:如果容器崩溃,K8S 会自动重启它。 自动替换:如果整个节点(服务器)宕机,K8S 会检测到它上面的容器失效,并在其他


对《DDD本质论》一文的解读
canonical_entropy2025/10/10

在《DDD本质论:从哲学到数学,再到工程实践的完整指南之理论篇》中,我们建立了一套从第一性原理出发的DDD理论体系。由于原文理论密度较高、概念间关系精微,为帮助读者更清晰地把握其思想脉络,我们设计了一项思想实验,并借助AI进行体系梳理与对比。 我们首先向AI提出以下问题: DDD领域驱动设计的概念有哪些?这些概念之间的相互关系是什么。如果要逐一去掉这些概念,你会按照什么顺序,为什么? 换言之,如果从第一性原理出发,如何逐步推导出这些概念的相互关系? 不要把任何技术看作是一个不可切分的整体,任何


tcp服务器
liuy96152025/10/9

🧩 一、总体架构思路 TCP 服务器的基本流程: 创建监听套接字 → 绑定 IP 和端口 → 监听端口 → 接受连接 → 通信收发 → 关闭连接 伪代码框架: int main() { int listen_fd = socket(AF_INET, SOCK_STREAM, 0); // 创建TCP套接字 bind(listen_fd, …); // 绑定地址和端口 listen(listen_fd, SOMAXCONN);


Vue3 EffectScope 源码解析与理解
excel2025/10/7

1. 全局变量与基础类定义 activeEffectScope:表示当前正在运行的 effect 作用域。 EffectScope 类:用来管理一组副作用(ReactiveEffect),提供生命周期控制。 import type { ReactiveEffect } from './effect' import { warn } from './warning' // 当前全局正在运行的作用域 export let activeEffectScope: EffectScope | und


Linus 眼中,编程 AI 的真实价值如何?
飞哥数智谈2025/10/6

今天刷到了一段视频,是 Linux 之父 Linus Torvalds 与 VMware 副总裁兼首席开源官 Dirk Hohndel 的一段对话。 内容挺有意思,分享给大家。 主要有两个话题: AI 只是打了鸡血的自动纠错 AI 幻觉带来了 bug 话题是由 Dirk Hohndel 提出,由 Linus Torvalds 进行回答的。 AI 是打了鸡血的自动纠错 针对这一点,Linus Torvalds 认为这一说法有一定的合理性,但 AI 在编程领域的真正潜力是可以成为一个识别“明显愚


从传输层协议到 UDP:轻量高效的传输选择
渡我白衣2025/10/5

前言 在计算机网络中,传输层是一个关键的层级,它为应用进程之间的通信提供了端到端的传输服务。常见的传输层协议有 TCP 和 UDP。前者强调可靠、面向连接的传输,而后者则提供轻量级、无连接的通信方式。传输层位于网络层之上、应用层之下,为进程之间提供端到端的数据传输服务。要理解 UDP 协议,我们需要先了解 传输层的功能与常见协议,再深入探讨为什么 UDP 在今天的网络环境中仍占据着举足轻重的地位。 一、传输层的基本概念 在 OSI 七层模型 和 TCP/IP 五层模型 中,传输层是第四层,它的主


磁盘的理解&&CHS和LBA地址转换
阑梦清川2025/10/3

1.对于磁盘的理解 首先就是我们的操作系统课本上面学习的这个磁盘的基本结构,比如下面的这个磁盘,磁头,磁头臂以及柱面,扇区的相关的概念; 针对于这个部分的内容,我自己也没有什么经验可以分享,因为这个东西就是固定的,唯一需要注意的就是结合图区进行理解,注意分别代表的是我们的图片里面画出来的这个磁盘的那一个具体的部分; 根据上面的内容,我们想要确定扇区只需要 CHS 三个部分即可,C 代表的就是我们的柱面,H 表示的是磁头,S 表示的是扇区,下面的这个是 ima 给出来的具体介绍,不懂就多去问问


2181、合并零之间的节点
Lenyiin2025/10/2

2181、[中等] 合并零之间的节点 1、问题描述: 给你一个链表的头节点 head ,该链表包含由 0 分隔开的一连串整数。链表的 开端 和 末尾 的节点都满足 Node.val == 0 。 对于每两个相邻的 0 ,请你将它们之间的所有节点合并成一个节点,其值是所有已合并节点的值之和。然后将所有 0 移除,修改后的链表不应该含有任何 0 。 返回修改后链表的头节点 head 。 2、代码思路: 跳过第一个节点:链表的开头和结尾都包含值为 0 的节点,我们从第二个节点开始处理(即

首页编辑器站点地图

Copyright © 2025 聚合阅读

License: CC BY-SA 4.0