关于XPath

节点匹配路径Xpath
在利用XSL进行转换的过程中,匹配的概念非常重要。在模板声明语句xsl:template match = ""和模板应用语句xsl:apply-templates select = ""中,用引号括起来的部分必须能够精确地定位节点。具体的定位方法则在XPath中给出。
   另外,也可以使用Xpath对XML文档进行搜索、定位。
之所以要引入XPath的概念,目的就是为了在匹配XML文档结构树时能够准确地找到某一个节点元素。可以把XPath比作文件管理路径:通过文件管理路径,可以按照一定的规则查找到所需要的文件;同样,依据XPath所制定的规则,也可以很方便地找到XML结构文档树中的任何一个节点。
在介绍XPath的匹配规则之前,我们先来看一些有关XPath的基本概念。首先要说的是XPath数据类型。XPath可分为四种数据类型:
节点集(node-set)
节点集是通过路径匹配返回的符合条件的一组节点的集合。其它类型的数据不能转换为节点集。
布尔值(boolean)
由函数或布尔表达式返回的条件匹配值,与一般语言中的布尔值相同,有true和false两个值。布尔值可以和数值类型、字符串类型相互转换。
字符串(string)
字符串即包含一系列字符的集合,XPath中提供了一系列的字符串函数。字符串可与数值类型、布尔值类型的数据相互转换。
数值(number)在XPath中数值为浮点数,可以是双精度64位浮点数。另外包括一些数值的特殊描述,如非数值NaN(Not-a-Number)、正无穷大infinity、负无穷大-infinity、正负0等等。number的整数值可以通过函数取得,另外,数值也可以和布尔类型、字符串类型相互转换。 
其中后三种数据类型与其它编程语言中相应的数据类型差不多,只是第一种数据类型是XML文档树的特有产物。另外,由于XPath包含的是对文档结构树的一系列操作,因此搞清楚XPath节点类型也是很必要的。由于XML文档的逻辑结构,一个XML文件可以包含元素、CDATA、注释、处理指令等逻辑要素,其中元素还可以包含属性,并可以利用属性来定义命名空间。相应地,在XPath中,将节点划分为七种节点类型:
根节点(Root Node)
根节点是一棵树的最上层,根节点是唯一的。树上其它所有元素节点都是它的子节点或后代节点。对根节点的处理机制与其它节点相同。在XSLT中对树的匹配总是先从根节点开始。
元素节点(Element Nodes)
元素节点对应于文档中的每一个元素,一个元素节点的子节点可以是元素节点、注释节点、处理指令节点和文本节点。可以为元素节点定义一个唯一的标识id。
元素节点都可以有扩展名,它是由两部分组成的:一部分是命名空间URI,另一部分是本地的命名。
文本节点(Text Nodes)
文本节点包含了一组字符数据,即CDATA中包含的字符。任何一个文本节点都不会有紧邻的兄弟文本节点,而且文本节点没有扩展名。
属性节点(Attribute Nodes)
每一个元素节点有一个相关联的属性节点集合,元素是每个属性节点的父节点,但属性节点却不是其父元素的子节点。这就是说,通过查找元素的子节点可以匹配出元素的属性节点,但反过来不成立,只是单向的。再有,元素的属性节点没有共享性,也就是说不同的元素节点不共有同一个属性节点。
对缺省属性的处理等同于定义了的属性。如果一个属性是在DTD声明的,但声明为#IMPLIED,而该属性没有在元素中定义,则该元素的属性节点集中不包含该属性。
此外,与属性相对应的属性节点都没有命名空间的声明。命名空间属性对应着另一种类型的节点。
命名空间节点(Namespace Nodes)
每一个元素节点都有一个相关的命名空间节点集。在XML文档中,命名空间是通过保留属性声明的,因此,在XPath中,该类节点与属性节点极为相似,它们与父元素之间的关系是单向的,并且不具有共享性。
处理指令节点(Processing Instruction Nodes)
处理指令节点对应于XML文档中的每一条处理指令。它也有扩展名,扩展名的本地命名指向处理对象,而命名空间部分为空。
注释节点(Comment Nodes)注释节点对应于文档中的注释。下面,我们来构造一棵XML文档树:
<A id="a1">
  <B id="b1">
    <C id="c1">
      <B name="b"/>
      <D id="d1"/>
      <E id="e1"/>
      <E id="e2"/>
    </C>
  </B>
  <B id="b2"/>
  <C id="c2">
    <B/>
    <D id="d2"/>
    <F/>
  </C>
  <E/>
</A>
现在,来实现一些利用Xpath使XML中节点匹配的基本方法。
路径匹配
路径匹配与文件路径的表示相仿,比较好理解。有以下几个符号:

符  号
含  义
举  例
匹配结果
/
指示节点路径
/A/C/D
节点"A"的子节点"C"的子节点"D",即id值为d2的D节点
/
根节点
//
所有路径以"//"后指定的子路径结尾的元素
//E
所有E元素,结果是所有三个E元素
//C/E
所有父节点为C的E元素,结果是id值为e1和e2的两个E元素
*
路径的通配符
/A/B/C/*
A元素→B元素→C元素下的所有子元素,即name值为b的B元素、id值为d1的D元素和id值为e1和e2的两个E元素
/*/*/D
上面有两级节点的D元素,匹配结果是id值为d2的D元素
//*
所有的元素
|
逻辑或
//B | //C
所有B元素和C元素
位置匹配
对于每一个元素,它的各个子元素是有序的。如:
举  例
含  义
匹配结果
/A/B/C[1]
A元素→B元素→C元素的第一个子元素
name值为b的B元素
/A/B/C[last()]
A元素→B元素→C元素的最后一个子元素
id值为e2的E元素
/A/B/C[position()>1]
A元素→B元素→C元素之下的位置号大于1的元素
id值为d1的D元素和两个具有id值的E元素
属性及属性值
在XPath中可以利用属性及属性值来匹配元素,要注意的是,元素的属性名前要有"@"前缀。例如:
举  例
含  义
匹配结果
//B[@id]
所有具有属性id的B元素
id值为b1和b2的两个B元素
//B[@*]
所有具有属性的B元素
两个具有id属性的B元素和一个具有name属性B元素
//B[not(@*)]
所有不具有属性的B元素
A元素→C元素下的B元素
//B[@id="b1"]
id值为b1的B元素
A元素下的B元素
亲属关系匹配
XML文档可归结为树型结构,因此任何一个节点都不是孤立的。通常我们把节点之间的归属关系归结为一种亲属关系,如父亲、孩子、祖先、后代、兄弟等等。在对元素进行匹配时,同样可以用到这些概念。例如:
举  例
含  义
匹配结果
//E/parent::*
所有E节点的父节点元素
id值为a1的A元素和id值为c1的C元素
//F/ancestor::*
所有F元素的祖先节点元素
id值为a1的A元素和id值为c2的C元素
/A/child::*
A的子元素
id值为b1、b2的B元素,id值为c2的C元素,以及没有任何属性的E元素
/A/descendant::*
A的所有后代元素
除A元素以外的所有其它元素
//F/self::*
所有F的自身元素
F元素本身
//F/ancestor-or-self::*
所有F元素及它的祖先节点元素
F元素、F元素的父节点C元素和A元素
/A/C/descendant-or-self::*
所有A元素→C元素及它们的后代元素
id值为c2的C元素、该元素的子元素B、D、F元素
/A/C/following-sibling::*
A元素→C元素的紧邻的后序所有兄弟节点元素
没有任何属性的E元素
/A/C/preceding-sibling::*
A元素→C元素的紧邻的前面所有兄弟节点元素
id值为b1和b2的两个B元素
/A/B/C/following::*
A元素→B元素→C元素的后序的所有元素
id为b2的B元素、无属性的C元素、无属性的B元素、id为d2的D元素、无属性的F元素、无属性的E元素。
/A/C/preceding::*
A元素→C元素的前面的所有元素
id为b2的B元素、id为e2的E元素、id为e1的E元素、id为d1的D元素、name为b的B元素、id为c1的C元素、id为b1的B元素
条件匹配
条件匹配就是利用一些函数的运算结果的布尔值来匹配符合条件的节点。常用于条件匹配的函数有四大类:节点函数、字符串函数、数值函数、布尔函数。
例如前面提到的last()、position()等等。这些功能函数可以帮助我们精确寻找需要的节点。
  

函数及功能
作用
count()功能
统计计数,返回符合条件的节点的个数
number()功能
将属性的值中的文本转换为数值
substring() 功能
语法:substring(value, start, length)

截取字符串
sum()功能
  
求和
 
这些功能只是XPath语法中的一部分,还有大量的功能函数没有介绍,而且目前XPath的语法仍然在不断发展中。通过这些函数我们可以实现更加复杂的查询和操作。
以上这些匹配方法中,用得最多的还要数路径匹配。依靠给出相对于当前路径的子路径来定位节点的。
<think>好的,我现在需要帮助用户了解如何正确使用XPath,包括教程和语法示例。根据用户提供的引用内容,我需要整理XPath的基本用法、谓语的使用方法以及实际应用示例。 首先,用户提到了XPath的路径表达式和谓语,这是核心部分。我需要从选取节点开始,解释路径表达式的结构,比如节点名称、斜杠的使用,以及通配符。然后,重点讲解谓语的作用,如何通过条件筛选节点,比如属性值比较、位置索引等。 接下来,要考虑实际应用场景,比如在XML和HTML文档中的使用,特别是在爬虫中如何结合lxml库解析HTML字符串。需要给出具体的Python代码示例,展示如何加载HTML并应用XPath表达式提取数据。 还要注意用户提到的引用内容,确保在回答中正确引用来源。例如,引用[1]和[2]提到谓语和路径表达式,引用[3]提供了Python代码示例。需要将这些内容自然地融入回答中,并在适当的位置添加引用标识。 用户可能需要的问题包括XPath语法基础、谓语的使用技巧、常见问题解决方法以及性能优化。因此,在相关问题部分,我需要列出这些方面,帮助用户进一步探索。 需要确保回答结构清晰,分点说明,每个部分都有示例代码或语法示例。同时,检查LaTeX格式是否正确,但根据用户的问题,可能数学公式不多,但如果有涉及计算的地方,比如谓语中的条件,可能需要用行内公式,比如比较数值时使用$x > 10$这样的表达式,但根据用户给的示例,可能不需要数学公式,重点在XPath语法。 最后,验证所有XPath示例的正确性,比如属性选择、位置索引,以及Python代码片段是否能正确运行。确保引用标记正确,没有遗漏。</think>### 如何正确使用XPath | XPath语法教程 #### 一、XPath基础语法 XPath通过**路径表达式**定位XML/HTML文档中的节点或节点集,语法类似文件系统路径[^2]: 1. **基本符号**: - `/`:从根节点开始选取 - `//`:从任意位置递归搜索节点 - `.`:当前节点 - `..`:父节点 - `@`:属性选择 - `*`:通配符(匹配任意节点) 2. **示例**: - `//div`:选取所有`<div>`标签 - `/html/body/p[1]`:选取`<body>`下第一个`<p>`标签 - `//a[@href]`:选取所有含`href`属性的`<a>`标签 --- #### 二、XPath谓语的使用(核心筛选条件) **谓语(Predicates)**是XPath中用于添加筛选条件的表达式,写在方括号`[]`内[^1]: 1. **属性筛选**: - `//div[@class="header"]`:选取`class`属性为`"header"`的`<div>`标签 - `//input[@type="text"]`:选取所有文本输入框 2. **位置索引**: - `//ul/li[3]`:选取第三个`<li>`子元素 - `//tr[last()]`:选取最后一个`<tr>`标签 3. **逻辑与比较**: - `//span[@price > 100]`:选取`price`属性大于100的`<span>` - `//p[contains(text(), "关键词")]`:选取文本包含“关键词”的`<p>`标签 --- #### 三、实际应用示例(爬虫场景) 在Python中使用`lxml`库解析HTML并应用XPath[^3]: ```python from lxml import etree # 示例:解析HTML字符串 html_str = """ <html> <body> <div class="content"> <h1>标题</h1> <p class="intro">段落1</p> <p class="detail">段落2</p> </div> </body> </html> """ html = etree.HTML(html_str) # 加载HTML # 提取所有<p>标签的文本 paragraphs = html.xpath("//p/text()") print(paragraphs) # 输出:['段落1', '段落2'] # 提取class为"intro"的段落 intro_para = html.xpath("//p[@class='intro']/text()")[0] print(intro_para) # 输出:段落1 ``` --- #### 四、常见问题与解决 1. **匹配失败**: - 检查路径是否完整(如缺少`//`或层级错误) - 确认属性值是否包含空格(需用`contains(@class, "partial")`) 2. **性能优化**: - 优先使用绝对路径(如`/html/body/div`比`//div`更快) - 减少`//`的使用频率,避免全局遍历 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值