Dom4j用Xpath获取节点——(六)
xml文档
<?xml version="1.0" encoding="utf-8"?> <书架> <书> <书名 name="ww">一本烂书!!</书名> <作者>武陟县</作者> <价格>200元</价格> </书> <书> <书名 name="xxxxxxxxxxx">Java中级</书名> <作者>打火机</作者> <价格>2000元</价格> </书> </书架>
Java代码
package Dom4j_XMLParser; import java.io.File; import java.util.List; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.Node; import org.dom4j.io.SAXReader; import org.junit.Test; public class Demo3 { /** * 测试path *@throws Exception */ @Test public void xpathTest() throws Exception { SAXReader reader = new SAXReader(); Document document = reader.read(new File("src/book.xml")); // 获取所有节点 List<Node> selectNodes = document.selectNodes( "//*" ); for(Node node :selectNodes){ System.out.println(node.asXML()); } // 取第一个书节点 Element node = (Element) document.selectSingleNode( "//书名" ); System.out.println(node.asXML()); //<书名 name="ww">一本烂书!!</书名> System.out.println(node.attributeValue("name")); System.out.println(node.getText()); // 取第二个书的书名 Node node1 = document.selectSingleNode( "/书架/书[last()]/书名" ); System.out.println(node1.getText()); } }
结果:
<书架> <书> <书名 name="ww">一本烂书!!</书名> <作者>武陟县</作者> <价格>200元</价格> </书> <书> <书名 name="xxxxxxxxxxx">Java中级</书名> <作者>打火机</作者> <价格>2000元</价格> </书> </书架> <书> <书名 name="ww">一本烂书!!</书名> <作者>武陟县</作者> <价格>200元</价格> </书> <书名 name="ww">一本烂书!!</书名> <作者>武陟县</作者> <价格>200元</价格> <书> <书名 name="xxxxxxxxxxx">Java中级</书名> <作者>打火机</作者> <价格>2000元</价格> </书> <书名 name="xxxxxxxxxxx">Java中级</书名> <作者>打火机</作者> <价格>2000元</价格> <书名 name="ww">一本烂书!!</书名> ww 一本烂书!! Java中级
什么是 XPath?
补充:dom4j用xpath获取节点之后修改属性后保存
例如:如下节点,需求是将court节点中cj属性是基层中没有q属性的节点找出来,赋予一个新的初始值,并将处理的节点单独写到另一个文件。
<?xml version="1.0" encoding="UTF-8"?> <courts> <court id="112" q="宣武区" cj="基层"/> <court id="113" q="宣武区" cj="基层"/> <court id="114" cj="基层"/> <court id="115" cj="中层"/> <court id="116"/> </courts>
代码如下:
package mvnpro; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.io.FileUtils; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; import lombok.extern.slf4j.Slf4j; @Slf4j public class XMLClient2 { private static Map<String, Object> idNames = new HashMap<>(); public static void main(String[] args) throws Exception { // 搜集区域信息 handleXML(); } private static void handleXML() throws Exception { SAXReader reader = new SAXReader(); Document document = reader.read(new File("F:/file/courts2.xml")); // 获取court节点(cj为基层并且不包含q属性的节点) String xpathPattern = "//court[@cj='基层' and not (@q)]"; List<Element> selectNodes = document.selectNodes(xpathPattern); if (CollectionUtils.isEmpty(selectNodes)) { return; } List<String> matchedElements = new ArrayList<>(); for (Element node : selectNodes) { node.setAttributeValue("q", "初始值"); // 记录到成功的列表 matchedElements.add(node.asXML()); } // 修改完节点之后直接保存,保存后的xml节点顺序不会变,而且会保存修改后的节点属性 write(document); // 保存处理成功和失败的记录到xml中便于手动排查 write(matchedElements, "F:/file/courts2-successful.xml"); } private static void write(List<String> nodes, String path) { if (CollectionUtils.isEmpty(nodes)) { return; } try { FileUtils.writeLines(new File(path), nodes); log.debug("writeLines success! path: {}", path); } catch (IOException e) { log.error("FileUtils.writeLines error", e); } } private static void write(Document document) throws Exception { OutputFormat format = OutputFormat.createPrettyPrint(); format.setEncoding("utf-8"); XMLWriter writer = new XMLWriter(new FileOutputStream("F:/file/courts2-1.xml"), format); writer.write(document); writer.close(); log.debug("write document success"); } }
结果:
counts2-1.xml如下:
<?xml version="1.0" encoding="utf-8"?> <courts> <court id="112" q="宣武区" cj="基层"/> <court id="113" q="宣武区" cj="基层"/> <court id="114" cj="基层" q="初始值"/> <court id="115" cj="中层"/> <court id="116"/> </courts>
courts2-successful.xml内容如下:
<court id="114" cj="基层" q="初始值"/>
Xml中文手册:
https://wenku.baidu.com/view/9fec55d86f1aff00bfd51e04.html
【当你用心写完每一篇博客之后,你会发现它比你用代码实现功能更有成就感!】
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了