(一)XPath简单介绍:
XPath是指:XML PATH Language。
特点:可以实现快速查询。
XPaht所在的包路径:
准备Xpath的包:
jaxen.jar:
XPATH包含:
(1)XPath 使用路径表达式在 XML 文档中进行导航 。
(2)XPath 包含一个标准函数库 。
Xpath通过以下方法使用:
找到包:org.dom4j.xpath.DefaultXPath
dom.selectNodes – 返回一个 List对像
dom.selectSingleNode – 返回一个Node对像
以下这些常用的方法可以使用XPath:
使用XPath的套路:
通过dom调用Node中的如下方法,每个方法中的参数用xpath表达式”—String型
一个小细节:
selectNodes(xpath),selectSingleNode(xpath),selectObject(xpath)
以上3个方法是Node中的方法,因此任意节点都可以调用,但所选择的却是document下面的所有符合xpath的节点或对象–不是当前调用节点子树范围(局部),而是整棵树(全局)
XPath简单介绍代码演示:
package cn.hncu.dom4j;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.junit.Test;
public class Dom4jXpathDemo {
/*使用xpath的套路:
通过dom调用Node中的如下方法,每个方法中的参数用 "xpath表达式"---String型
selectNodes(xpath), selectSingleNode(xpath), selectObject(xpath)
※一个小细节:
以上3个方法是Node中的方法,因此任意节点都可以调用,
但所选择的却是document下面的所有符合xpath的节点或对象
--不是当前调用节点子树范围(局部),而是整棵树(全局)
*/
@Test //※注意,dom4j使用xpath时,要导入一个它的依赖包:jaxen.jar
public void demo1() throws Exception{
Document dom = new SAXReader().read("./xml/contact.xml");
//参数放xpath ---任意位置的<name>
//List<Node> list = dom.selectNodes("//name");
//参数放xpath ---<contact>后代节点中任意位置的<name>
List<Node> list = dom.selectNodes("//contact//name");
//参数放xpath ---<contact>直接孩子节点中的<name>
//List<Node> list = dom.selectNodes("//contact/name");
System.out.println(list.size());
for( Node node:list){
System.out.println(node.getText());
}
}
@Test//演示根据属性来用xpath定位---登录模块常用
public void demo2() throws Exception{
Document dom = new SAXReader().read("./xml/contact.xml");
Node node = dom.selectSingleNode("//user[@name='Jack'][@pwd='1234']");//参数放xpath
if(node==null){
System.out.println("登录失败");
}else{
System.out.println("登录成功");
}
}
}
(二)XPath的基本语法:
(1)基本的XPath语法类似于在一个文件系统中定位文件,如果路径以斜线 / 开始, 那么该路径就表示到一个元素的绝对路径:
/AAA
选择根元素AAA/AAA/CCC
选择AAA 的所有CCC子元素/AAA/DDD/BBB
选择AAA 的子元素DDD的所有子元素(2)如果路径以双斜线 // 开头, 则表示选择文档中所有满足双斜线//之后规则的元素(无论层级关系):
//BBB
选择所有BBB元素//DDD/BBB
选择所有父元素是DDD的BBB元素(3)星号 * 表示选择所有由星号之前的路径所定位的元素:
/AAA/CCC/DDD/*
选择所有路径依附于/AAA/CCC/DDD 的元素
/*/*/*/
BBB
选择所有的有3个祖先元素的BBB元素//*
选择所有元素(4)方块号里的表达式可以进一步的指定元素(类似于数组脚标), 其中数字表示元素在选择集里的位置, 而last()函数则表示选择集中的最后一个元素:
/AAA/BBB[1]
选择AAA 的第一个BBB子元素/AAA/BBB[last()]
选择AAA 的最后一个BBB子元素(5)属性通过前缀 @ 来指定:
//@id
选择所有的id属性//BBB[@id]
选择有id属性的BBB元素//BBB[@name]
选择有name属性的BBB元素//BBB[@*]
选择有任意属性的BBB元素//BBB[not(@*)]
选择没有属性的BBB元素(6)属性的值可以被用来作为选择的准则, normalize-space函数删除了前部和尾部的空格, 并且把连续的空格串替换
为一个单一的空格://BBB[@id=’b1’]
选择含有属性id且其值为’b1’的BBB元素//BBB[@name=’bbb’]
选择含有属性name且其值为’bbb’的BBB元素//BBB[normalize-space(@name)=’bbb’]
选择含有属性name且其值(在用normalize-space函数去掉前后空格后)为’bbb’的BBB元素(7)count()函数可以计数所选元素的个数:
//*[count(BBB)=2]
选择含有2个BBB子元素的元素
//*[count(*)=2]
选择含有2个子元素的元素(8)name()函数返回元素的名称, start-with()函数在该函数的第一个参数字符串是以第二个参数字符开始的情况返回true, contains()函数当其第一个字符串参数包含有第二个字符串参数时返回true:
//*[name()=’BBB’]
选择所有名称为BBB的元素(这里等价于//BBB)//*[starts-with(name(),’B’)]
选择所有名称以”B”起始的元素//*[contains(name(),’C’)]
选择所有名称包含”C”的元素(9)string-length函数返回字符串的字符数,你应该用<替代<, 用
>
;代替>://*[string-length(name()) = 3]
选择名字长度为3的元素//*[string-length(name()) < 3]
选择名字长度小于3的元素//*[string-length(name()) > 3]
选择名字长度大于3的元素(10)多个路径可以用分隔符 | 合并在一起:
//CCC | //BBB
选择所有的CCC和BBB元素/AAA/EEE | //BBB
选择所有的BBB元素和所有是AAA 的子元素的EEE元素/AAA/EEE | //DDD/CCC | /AAA | //BBB
可以合并的路径数目没有限制(11)child轴(axis)包含上下文节点的子元素, 作为默认的轴,可以忽略不写:
/AAA
等价于 /child::AAA/child::AAA
等价于/AAA/AAA/BBB
等价于/child::AAA/child::BBB/child::AAA/child::BBB
等价于/AAA/BBB(12)descendant (后代)轴包含上下文节点的后代,一个后代是指子节点或者子节点的子节点等等, 因此descendant轴
不会包含属性和命名空间节点:/descendant::*
选择文档根元素的所有后代.即所有的元素被选择/AAA/BBB/descendant::*
选择/AAA/BBB 的所有后代元素//CCC/descendant::*
选择在祖先元素中有CCC的所有元素//CCC/descendant::DDD
选择所有以CCC为祖先元素的DDD元素(13)parent轴(axis)包含上下文节点的父节点, 如果有父节点的话:
//DDD/parent::*
选择DDD元素的所有父节点(14)ancestor轴(axis)包含上下节点的祖先节点, 该祖先节点由其上下文节点的父节点以及父节点的父节点等等诸如此类的节点构成,所以ancestor轴总是包含有根节点,除非上下文节点就是根节点本身:
/AAA/BBB/DDD/CCC/EEE/ancestor::*
选择一个绝对路径上的所有节点//FFF/ancestor::*
选择FFF元素的祖先节点(15)following -sibling轴(axis)包含上下文节点之后的所有兄弟节点:
/AAA/BBB/following -sibling::*
//CCC/following-sibling::*
(16)preceding-sibling 轴(axis)包含上下文节点之前的所有兄弟节点:
/AAA/XXX/preceding -sibling::*
//CCC/preceding-sibling::*
(17)following 轴(axis)包含同一文档中按文档顺序位于上下文节点之后的所有节点, 除了祖先节点,属性节点和命名空
间节点:/AAA/XXX/following::*
//ZZZ/following::*
(18)following 轴(axis)包含同一文档中按文档顺序位于上下文节点之前的所有节点, 除了祖先节点,属性节点和命名空间节点:
/AAA/XXX/preceding::*
//GGG/preceding::*
(19)descendant-or-self 轴(axis)包含上下文节点本身和该节点的后代节点:
/AAA/XXX/descendant -or-self::*
//CCC/descendant-or-self::*
(20)ancestor-or-self 轴(axis)包含上下文节点本身和该节点的祖先节点:
/AAA/XXX/DDD/EEE/ancestor -or-self::*
//GGG/ancestor-or-self::*
(21)ancestor, descendant, following, preceding 和self轴(axis)分割了XML文档(忽略属性节点和命名空间节点), 不能
交迭, 而一起使用则包含所有节点://GGG/ancestor::*
//GGG/descendant::*
//GGG/following::*
//GGG/preceding::*
//GGG/self::*
//GGG/ancestor::* |//GGG/descendant::* | //GGG/following::*| //GGG/preceding::* | //GGG/self::*
(22)div运算符做浮点除法运算, mod运算符做求余运算, floor函数返回不大于参数的最大整数(趋近于正无穷),
ceiling返回不小于参数的最小整数(趋近于负无穷)://BBB[position() mod 2 = 0 ]
选择偶数位置的BBB元素//BBB[ position() = floor(last() div 2 + 0.5) or position() = ceiling(last() div 2+ 0.5) ]
选择中间的BBB元素//CCC[ position() = floor(last() div 2 + 0.5) or position() = ceiling(last() div 2+ 0.5) ]
选择中间的CCC元素