groovy XmlParser 递归遍历 xml 文件,修改并保存

在这里插入图片描述

使用 groovy.util.XmlParser 解析 xml 文件,对文件进行修改(新增标签),然后保存。

是不是 XmlParser 没有提供方法遍历每个节点,难道要自己写?

什么是递归?

不用说,想必都懂得~

import ***.XmlNodeCallback;
import ***.PluginLog;import org.xml.sax.SAXException;import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardOpenOption;
import java.util.List;import javax.xml.parsers.ParserConfigurationException;import groovy.util.Node;
import groovy.util.XmlParser;
import groovy.xml.XmlUtil;public class PluginXmlUtil {/*** * @param xmlFile   需要解析的 xml 文件* @param callback  回调每一个标签 node,可以对 node 进行 CURD* @return*/public static Node parseXml(File xmlFile, XmlNodeCallback callback) {if (CommUtils.isEmptyOrNoExists(xmlFile)) {return null;}try {Node rootNode = new XmlParser().parse(xmlFile);traverseNode(rootNode, callback);return rootNode;} catch (IOException e) {} catch (SAXException e) {} catch (ParserConfigurationException e) {}return null;}/*** * @param node          需要保存的往往是根节点 node(当然保存你想要的任意节点也是可以)* @param targetFile    保存文件* @return*/public static boolean saveNodeToFile(Node node, File targetFile) {if (node == null || targetFile == null) {return false;}try {// 使用 groovy 提供的 xml 序列化工具获得原始字符串String finalContent = XmlUtil.serialize(node);if (CommUtils.isEmptyOrNoExists(finalContent)) {return false;}// 使用 TRUNCATE_EXISTING,如果文件存在,那么截取长度为0(也就是覆盖文件内容),然后写入新内容Files.write(targetFile.toPath(), finalContent.getBytes(), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);return true;} catch (IOException e) {}return false;}/*** 递归会写吧~* * @param rootNode      根节点* @param callback      把每个 node 回调返回给外部,在回调中可操作 node 等*/private static void traverseNode(Node node, XmlNodeCallback callback) {if (node == null) {return;}if (callback != null) {callback.onNode(node);}List<Object> children = node.children();boolean hasChildren = children != null && !children.isEmpty();if (hasChildren) {for (Object child : children) {// 仅遍历 node 类型,因为 children 可存在 String 等,调用递归就不合适了// 比如存在 <name>lf</name>,其中值 lf 也是作为 children 的一个元素,// 目前不对他进行递归(如果需要回调给外部,也可以在 XmlNodeCallback 新增一个接口,通过 callback 回调数据) if (child instanceof Node) {traverseNode((Node) child, callback);} else {PluginLog.d("traverseNode: " + child.getClass() + "  val:" + child);}}}}
}

使用接口,回调每一个递归遍历到的 node,在回调中处理逻辑

public interface XmlNodeCallback {void onNode(Node node);
}

直接使用

  File xmlFile = new File(****)def rootNode = PluginXmlUtil.parseXml(xmlFile, new XmlNodeCallback() {@Overridevoid onNode(Node node) {if (node == null) {return}String nodeName = node.name()String[] nodeAttr = node.attributes()if (CommUtils.isEmptyOrNoExists(nodeName)) {return}PluginLog.d("nodeName:" + nodeName + "  nodeAttr:  " + nodeAttr + " value: " + node.value)// TODO: 2024/1/10  处理你的逻辑}})// 比如,我要在跟节点下面添加一个标签rootNode.append(ArgUtil.genDefaultBaseConfigNode())//然后保存修改def saveSuccess = PluginXmlUtil.saveNodeToFile(rootNode, xmlFile)

默认配置

package ***.utils;import org.xml.sax.SAXException;import java.io.IOException;import javax.xml.parsers.ParserConfigurationException;import groovy.util.Node;
import groovy.util.XmlParser;public class ArgUtil {public static Node genDefaultBaseConfigNode() throws ParserConfigurationException, SAXException, IOException {return new XmlParser().parseText("<base-config cleartextTrafficPermitted=\"true\">\n" +"        <trust-anchors>\n" +"            <certificates src=\"user\" />\n" +"            <certificates src=\"system\" />\n" +"        </trust-anchors>\n" +"    </base-config>");}public static Node genDefaultTrustAnchorsNode() throws ParserConfigurationException, SAXException, IOException {return new XmlParser().parseText("<trust-anchors>\n" +"            <certificates src=\"user\" />\n" +"            <certificates src=\"system\" />\n" +"        </trust-anchors>");}public static Node genDefaultCertificatesNode(String value) throws ParserConfigurationException, SAXException, IOException {return new XmlParser().parseText("<certificates src=" + value + " />");}
}

学会了新增,删除、修改都不是问题吧~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/235162.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何通过兴趣爱好选职业?

一个错误的选择&#xff0c;可能造成终身的遗憾&#xff0c;一个正确的选择&#xff0c;可以让我们少奋斗几十年。所以无论现在付出多少代价&#xff0c;多花一些时间&#xff0c;去研究以下未来的职业方向&#xff0c;这是值得的。 职业定位&#xff08;专业定位&#xff09;…

红队打靶练习:TOMMY BOY: 1

目录 信息收集 1、arp 2、nmap 3、nikto 4、whatweb WEB robots.txt get flag1 get flag2 FTP登录 文件下载 更改代理 ffuf爆破 get flag3 crunch密码生成 wpscan 1、密码爆破 2、登录wordpress ssh登录 get flag4 信息收集 get flag5 信息收集 1、arp …

阿里云c8i服务器CPU性能、架构及费用测评

阿里云第八代云服务器ECS计算型c8i实例&#xff0c;CPU采用Intel Xeon Emerald Rapids或者Intel Xeon Sapphire Rapids&#xff0c;主频不低于2.7 GHz&#xff0c;全核睿频3.2&#xff0c;阿里云百科aliyunbaike.com分享阿里云c8i服务器CPU处理器型号、存储、网络、安全、使用场…

【uniapp】APP打包上架应用商-注意事项

初雪云-uniapp启动图自定义生成&#xff08;支持一键生成storyboard&#xff09; HBuilderX需要的自定义storyboard文件格式为 " zip压缩包 " 一、“Android” — 设置targetSdkVersion 小米、OPPO、vivo、华为等主流应用商店&#xff0c;将于2023年12月采用 targetS…

多链混沌:Layer2 格局演变与跨链流动性的新探索

点击查看原文&#xff1a;多链混沌&#xff1a;Layer2 格局演变与跨链流动性的新探索 如今的 Crypto 是一个由多链构成的混沌世界。曾经&#xff0c;以太坊聚集了加密世界绝大多数的流动性与 DeFi 应用&#xff0c;但现在其 TVL 占比已经降到 60% 以下&#xff0c;并仍处于下降…

golang实现加密解密文档

golang实现加密解密文档 package mainimport ("bytes""crypto/aes""crypto/cipher""crypto/rand""encoding/base64""flag""fmt""io""io/ioutil" )func main() {encodePtr : flag.…

【开发小程序多少钱?智创开发】

开发一个小程序费用主要看做什么和怎么做&#xff1f; 第一部分&#xff1a;做什么&#xff1f; 做什么是指功能部分&#xff0c;开发的功能不一样&#xff0c;耗时也就不一样&#xff0c;价格自然也就不一样了。就好比买房&#xff0c;套二的公寓和别墅价格自然差距很大。所…

【python基础教程】print输出函数和range()函数的正确使用方式

嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 print()有多个参数&#xff0c;参数个数不固定。 有四个关键字参数&#xff08;sep end file flush&#xff09;&#xff0c;这四个关键字参数都有默认值。 print作用是将objects的内容输出到file中&#xff0c;objects中的…

uni-app的学习【第二节】

四 路由配置及页面跳转 (1)路由配置 uni-app页面路由全部交给框架统一管理,需要在pages.json里配置每个路由页面的路径以及页面样式(类似小程序在app.json中配置页面路由) (2)路由跳转 uni-app有两种页面路由跳转方式:使用navigator组件跳转(标签式导航)、调用API跳…

AI人工智能虚拟现实行业发展分析

AI人工智能和虚拟现实是当今科技领域最受关注和研究的两个领域。这两项技术的迅速发展给各行各业带来了巨大的变革和机遇。在过去的几年里&#xff0c;AI和虚拟现实已经取得了显著的进展&#xff0c;并且有着广阔的发展前景。 AI人工智能作为一种模拟人类智能的技术&#xff0…

LangChain v0.1.0:大模型应用技术革新的里程碑

LangChain v0.1.0 最新版本发布, 大模型应用技术革新的里程碑 LangChain官方宣布发布了langchain 0.1.0,这是Langchain第一个稳定版本。支持 Python 和 JavaScript。 Langchain简介 LangChain已经存在了一年多,随着LangChain成长为构建LLM应用程序的默认框架,LangChain已…

详解Keras:keras.preprocessing.image

keras.preprocessing.image Keras 库中的一个模块&#xff0c;用于处理和增强图像数据&#xff0c;它提供了一些实用的函数&#xff0c;如图像的加载、预处理、增强等。 常用函数 1、load_img 用于加载图像文件&#xff0c;并返回一个 NumPy 数组表示该图像 示例 from ker…

JVM基础(1)——JVM类加载机制

作者简介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中兴通讯、美团架构师&#xff0c;现某互联网公司CTO 联系qq&#xff1a;184480602&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗互联网寒冬 学习必须往深处挖&…

2024--Django平台开发-Django知识点(五)

day05 django知识点 今日概要&#xff1a; 中间件 【使用】【源码】cookie 【使用】【源码 - Django底层请求本质】session【使用】【源码 - 数据库请求周期中间件】 1.中间件 1.1 使用 编写类&#xff0c;在类型定义&#xff1a;process_request、process_view、process_…

Unity Editor实用功能:Hierarchy面板的对象上绘制按按钮并响应

目录 需求描述上代码打个赏吧 需求描述 现在有这样一个需求&#xff1a; 在Hierarchy面板的对象上绘制按钮点击按钮&#xff0c;弹出菜单再点击菜单项目响应自定义操作在这里的响应主要是复制对象层级路路径 看具体效果请看动图&#xff1a; 注&#xff1a; 核心是对Edito…

控制el-table的列显示隐藏

控制el-table的列显示隐藏&#xff0c;一般的话可以通过循环来实现&#xff0c;但是假如业务及页面比较复杂的话&#xff0c;list数组循环并不好用。 在我们的页面中el-table-column是固定的&#xff0c;因为现在是对现有的进行维护和迭代更新。 对需要控制列显示隐藏的页面进…

【EI会议征稿通知】第三届仿真设计与计算建模国际学术会议(SDCM 2024)

The 3rd International Conference on Simulation Design and Computational Modeling 第三届仿真设计与计算建模国际学术会议&#xff08;SDCM 2024&#xff09; 第三届仿真设计与计算建模国际会议&#xff08;SDCM 2024&#xff09;将于 4 月 26-28 日在中国重庆召开。第二届…

【博士每天一篇文-算法】Graph Structure of Neural Networks

阅读时间&#xff1a;2023-11-12 1 介绍 年份&#xff1a;2020 作者&#xff1a;尤家轩 斯坦福大学 期刊&#xff1a; International Conference on Machine Learning. 引用量&#xff1a;130 论文探讨了神经网络的图结构与其预测性能之间的关系。作者提出了一种新的基于图的…

【leetcode】力扣算法之旋转图像【难度中等】

题目描述 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 用例 输入&#xff1a; matrix [[1,2,3],[4,5,6],[7,8,9]] 输出&…

java 体育明星管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 java Web 体育明星管理系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysq…