使用
groovy.util.XmlParser
解析 xml 文件,对文件进行修改(新增标签),然后保存。
是不是 XmlParser 没有提供方法遍历每个节点,难道要自己写?
什么是递归?
不用说,想必都懂得~
import***.XmlNodeCallback;import***.PluginLog;importorg.xml.sax.SAXException;importjava.io.File;importjava.io.IOException;importjava.nio.file.Files;importjava.nio.file.StandardOpenOption;importjava.util.List;importjavax.xml.parsers.ParserConfigurationException;importgroovy.util.Node;importgroovy.util.XmlParser;importgroovy.xml.XmlUtil;publicclassPluginXmlUtil{/**
*
* @param xmlFile 需要解析的 xml 文件
* @param callback 回调每一个标签 node,可以对 node 进行 CURD
* @return
*/publicstaticNodeparseXml(File xmlFile,XmlNodeCallback callback){if(CommUtils.isEmptyOrNoExists(xmlFile)){returnnull;}try{Node rootNode =newXmlParser().parse(xmlFile);traverseNode(rootNode, callback);return rootNode;}catch(IOException e){}catch(SAXException e){}catch(ParserConfigurationException e){}returnnull;}/**
*
* @param node 需要保存的往往是根节点 node(当然保存你想要的任意节点也是可以)
* @param targetFile 保存文件
* @return
*/publicstaticbooleansaveNodeToFile(Node node,File targetFile){if(node ==null|| targetFile ==null){returnfalse;}try{// 使用 groovy 提供的 xml 序列化工具获得原始字符串String finalContent =XmlUtil.serialize(node);if(CommUtils.isEmptyOrNoExists(finalContent)){returnfalse;}// 使用 TRUNCATE_EXISTING,如果文件存在,那么截取长度为0(也就是覆盖文件内容),然后写入新内容Files.write(targetFile.toPath(), finalContent.getBytes(),StandardOpenOption.CREATE,StandardOpenOption.TRUNCATE_EXISTING);returntrue;}catch(IOException e){}returnfalse;}/**
* 递归会写吧~
*
* @param rootNode 根节点
* @param callback 把每个 node 回调返回给外部,在回调中可操作 node 等
*/privatestaticvoidtraverseNode(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 instanceofNode){traverseNode((Node) child, callback);}else{PluginLog.d("traverseNode: "+ child.getClass()+" val:"+ child);}}}}}
使用接口,回调每一个递归遍历到的 node,在回调中处理逻辑
publicinterfaceXmlNodeCallback{voidonNode(Node node);}
直接使用
File xmlFile =newFile(****)def rootNode = PluginXmlUtil.parseXml(xmlFile,newXmlNodeCallback(){@OverridevoidonNode(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;importorg.xml.sax.SAXException;importjava.io.IOException;importjavax.xml.parsers.ParserConfigurationException;importgroovy.util.Node;importgroovy.util.XmlParser;publicclassArgUtil{publicstaticNodegenDefaultBaseConfigNode()throwsParserConfigurationException,SAXException,IOException{returnnewXmlParser().parseText("<base-config cleartextTrafficPermitted=\"true\">\n"+" <trust-anchors>\n"+" <certificates src=\"user\" />\n"+" <certificates src=\"system\" />\n"+" </trust-anchors>\n"+" </base-config>");}publicstaticNodegenDefaultTrustAnchorsNode()throwsParserConfigurationException,SAXException,IOException{returnnewXmlParser().parseText("<trust-anchors>\n"+" <certificates src=\"user\" />\n"+" <certificates src=\"system\" />\n"+" </trust-anchors>");}publicstaticNodegenDefaultCertificatesNode(String value)throwsParserConfigurationException,SAXException,IOException{returnnewXmlParser().parseText("<certificates src="+ value +" />");}}
学会了新增,删除、修改都不是问题吧~
本文转载自: https://blog.csdn.net/printf123scanf/article/details/135501166
版权归原作者 l and 所有, 如有侵权,请联系我们删除。
版权归原作者 l and 所有, 如有侵权,请联系我们删除。