JavaEE XML XPath
JavaEE XML XPath
@author ixenos
XPath技术
1 引入
问题:当使用dom4j查询比较深的层次结构的节点(标签,属性,文本),比较麻烦!!!需要遍历DOM树的众多节点来进行查找!
比如rootEle.element(“dsfs”).element(“sdfsf”)element(“sdfsf”). element(“aim”)
2 xPath作用
主要是用于快速获取所需的节点对象。
(XSLT中的match属性的值就使用XPath!!!)
3 在dom4j中如何使用xPath技术
1)导入xPath支持jar包 。 jaxen-1.1-beta-6.jar
2)使用xpath方法
List<Node> selectNodes("xpath表达式"); 查询多个节点对象
Node selectSingleNode("xpath表达式"); 查询一个节点对象
4 xPath语法
/ 绝对路径 表示从xml的根位置开始或子元素(一个层次结构)
// 相对路径 表示不分任何层次结构的选择元素。
* 通配符 表示匹配所有元素
[] 条件 表示选择什么条件下的元素
@ 属性 表示选择属性节点
and 关系 表示条件的与关系(等价于&&)
text() 文本 表示选择文本内容
示例:
XPath可以描述XML文档中的一个节点集
/grib/row
描述了grib的子元素(每一个grib)中所有的row元素
/grib/row[1]
用[]选择特定元素,这表示第一行(索引从1开始)
/grib/row[1]/cell[1]/@anchor
用@得到属性值,这描述了第一行第一个单元格的anchor属性
/grib/row/cell/@anchor
描述了作为根元素的grib的子元素的那些row元素中所有cell的anchor属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | /** * 1. / 绝对路径 表示从xml的根位置开始或子元素(一个层次结构) */ xpath = "/contactList" ; xpath = "/contactList/contact" ; /** * 2. // 相对路径 表示不分任何层次结构的选择元素。 */ xpath = "//contact/name" ; xpath = "//name" ; /** * 3. * 通配符 表示匹配所有元素 */ xpath = "/contactList/*" ; //根标签contactList下的所有子标签 xpath = "/contactList//*" ;//根标签contactList下的所有标签(不分层次结构) /** * 4. [] 条件 表示选择什么条件下的元素 */ //带有id属性的contact标签 xpath = "//contact[@id]" ; //第二个的contact标签 xpath = "//contact[2]" ; //选择最后一个contact标签 xpath = "//contact[last()]" ; /** * 5. @ 属性 表示选择属性节点 */ xpath = "//@id" ; //选择id属性节点对象,返回的是Attribute对象 xpath = "//contact[not(@id)]" ;//选择不包含id属性的contact标签节点 xpath = "//contact[@id='002']" ;//选择id属性值为 002 的contact标签 xpath = "//contact[@id='001' and @name='eric']" ;//选择id属性值为 001 ,且name属性为eric的contact标签 /** *6. text() 表示选择文本内容 */ //选择name标签下的文本内容,返回Text对象 xpath = "//name/text()" ; xpath = "//contact/name[text()='张三']" ;//选择姓名为张三的name标签 |
更多XPath表达式请看XPath Tutorial
Demo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | import java.io.File; import java.io.FileOutputStream; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; /** * 第一个xpath程序 * @author ixenos * */ public class Demo1 { public static void main(String[] args) throws Exception{ /** * 需求: 删除id值为2的学生标签 */ Document doc = new SAXReader().read( new File( "e:/student.xml" )); //1.查询id为2的学生标签 //使用xpath技术 Element stuElem = (Element)doc.selectSingleNode( "//Student[@id='2']" ); //2.删除标签 stuElem.detach(); //3.写出xml文件 FileOutputStream out = new FileOutputStream( "e:/student.xml" ); OutputFormat format = OutputFormat.createPrettyPrint(); format.setEncoding( "utf-8" ); XMLWriter writer = new XMLWriter(out,format); writer.write(doc); writer.close(); } } |
简要示例
1) 用XPath定位标签,进行修改操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | package com.ixenos.xpath; import java.util.List; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader; import com.ixenos.dom4j.CreateXML; /** * 在TestXPath的基础上改进了: * 将精准定位全交给XPath去做,因此删除了modEle多余的属性定位判断 * * @author ixenos * */ public class TestXPath2 { /** * 读取XML文件生成Docment * * @throws Exception */ public static Document getDoc(String path) throws Exception { Document doc = new SAXReader().read(path); return doc; } /** * XPath定位标签 */ @SuppressWarnings ( "unchecked" ) public static List<Element> getEle(Document doc, String xpath) { return (List<Element>)doc.selectNodes(xpath); } /** * 对指定标签的子节点进行修改 * * @param func * 修改功能选择 * @param eleList * 被修改的标签list * @param aimChild * 想要修改的子标签 * @param aimChildText * 想要修改的新的子标签文本值 */ public static void modEle(String func, List<Element> eleList, String aimChild, String aimChildText) { // 取出 for (Element ele : eleList) { // 修改功能选择 if ( "delete" .equals(func)) { ele.detach(); } else if ( "modify" .equals(func)) { // 修改指定子节点的文本值 // element(name)指定第一个标签名为name的标签 // setText修改Text,addText追加Text ele.element(aimChild).setText(aimChildText); } } } /** * 将DOM树输出为XML文件 * * @throws Exception */ public static void writeXML(Document doc, Boolean pretty, String encoding) throws Exception { CreateXML.writeXML(doc, pretty, encoding); } /** * 测试 * * @param args * @throws Exception */ public static void main(String[] args) throws Exception { Document doc = getDoc( "demo.xml" ); //得到所有id属性值为2的Student标签 List<Element> eleList = getEle(doc, "//Student[@id='2']" ); modEle( "modify" , eleList, "name" , "尔雅" ); // modEle("delete", eleList, null, null); writeXML(doc, true , "utf-8" ); } } |
修改结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <? xml version="1.0" encoding="utf-8"?> < Students > < Student id="1"> < name >张三</ name > < gender >男</ gender > < grade >物联网一般</ grade > < address >广州白云</ address > </ Student > < Student id="2"> < name >尔雅</ name > < gender >女</ gender > < grade >物联网二班</ grade > < address >广州海珠</ address > </ Student > </ Students > |
2) 用XPath读取一个规范的html文件(比如xhtml)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | import java.io.File; import java.util.Iterator; import java.util.List; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader; /** * 使用xpath技术读取一个规范的html文档 * @author ixenos * */ public class Demo4 { public static void main(String[] args) throws Exception{ Document doc = new SAXReader().read( new File( "./src/personList.html" )); //System.out.println(doc); //读取title标签 Element titleElem = (Element)doc.selectSingleNode( "//title" ); String title = titleElem.getText(); System.out.println(title); /** * 练习:读取联系人的所有信息 * 按照以下格式输出: * 编号:001 姓名:张三 性别:男 年龄:18 地址:xxxx 电话: xxxx * 编号:002 姓名:李四 性别:女 年龄:20 地址:xxxx 电话: xxxx * ...... */ //1.读取出所有tbody中的tr标签 List<Element> list = (List<Element>)doc.selectNodes( "//tbody/tr" ); //2.遍历 for (Element elem : list) { //编号 //String id = ((Element)elem.elements().get(0)).getText(); String id = elem.selectSingleNode( "td[1]" ).getText(); //姓名 String name = ((Element)elem.elements().get( 1 )).getText(); //性别 String gender = ((Element)elem.elements().get( 2 )).getText(); //年龄 String age = ((Element)elem.elements().get( 3 )).getText(); //地址 String address = ((Element)elem.elements().get( 4 )).getText(); //电话 String phone = ((Element)elem.elements().get( 5 )).getText(); System.out.println( "编号:" +id+ "\t姓名:" +name+ "\t性别:" + gender+ "\t年龄:" + age+ "\t地址:" +address+ "\t电话:" +phone); } } } |
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
· ASP.NET Core 模型验证消息的本地化新姿势
· 从零开始开发一个 MCP Server!
· ThreeJs-16智慧城市项目(重磅以及未来发展ai)
· .NET 原生驾驭 AI 新基建实战系列(一):向量数据库的应用与畅想
· Ai满嘴顺口溜,想考研?浪费我几个小时
· Browser-use 详细介绍&使用文档