了解Xpath之前先了解下XML、HTML。如果完全不知道是什么,建议系统学习HTML、XML下阅读下文。
XML
可扩展标记语言(英语:Extensible Markup Language,简称:XML),是一种标记语言。标记指计算机所能理解的信息符号,通过此种标记,计算机之间可以处理包含各种信息的文章等。如何定义这些标记,既可以选择国际通用的标记语言,比如HTML,也可以使用像XML这样由相关人士自由决定的标记语言,这就是语言的可扩展性。XML是从标准通用标记语言(SGML)中简化修改出来的。它主要用到的有可扩展标记语言、可扩展样式语言(XSL)、XBRL和XPath等。
示例-0
1 | <note> |
HTML
超文本标记语言(英语:HyperText Markup Language,简称:HTML)是一种用于创建网页的标准标记语言。HTML是一种基础技术,常与CSS、JavaScript一起被众多网站用于设计令人赏心悦目的网页、网页应用程序以及移动应用程序的用户界面。网页浏览器可以读取HTML文件,并将其渲染成可视化网页。HTML描述了一个网站的结构语义随着线索的呈现,使之成为一种标记语言而非编程语言。
HTML元素是构建网站的基石。HTML允许嵌入图像与对象,并且可以用于创建交互式表单,它被用来结构化信息——例如标题、段落和列表等等,也可用来在一定程度上描述文档的外观和语义。HTML的语言形式为尖括号包围的HTML元素(如
<html>
),浏览器使用HTML标签和脚本来诠释网页内容,但不会将它们显示在页面上。HTML可以嵌入如JavaScript的脚本语言,它们会影响HTML网页的行为。网页浏览器也可以引用层叠样式表(CSS)来定义文本和其它元素的外观与布局。维护HTML和CSS标准的组织万维网联盟(W3C)鼓励人们使用CSS替代一些用于表现的HTML元素。
示例-1
1 | <html> |
XML和HTML有啥关系呢?
- XML是被设计用来描述数据的,重点是:什么是数据,如何存放数据。
- HTML是被设计用来显示数据的,重点是:显示数据以及如何显示数据更好上面。
Xpath
XPath即为XML路径语言(XML Path Language),它是一种用来确定XML文档中某部分位置的语言。
XPath基于XML的树状结构,提供在数据结构树中找寻节点的能力。起初XPath的提出的初衷是将其作为一个通用的、介于XPointer间的语法模型。但是XPath很快的被开发者采用来当作小型查询语言。XPath 用于在 XML 文档中通过元素和属性进行导航。
标识法
最常见的XPath表达式是路径表达式(XPath这一名称的另一来源)。路径表达式是从一个XML节点(当前的上下文节点)到另一个节点、或一组节点的书面步骤顺序。这些步骤以“/”字符分开,每一步有三个构成成分:
- 轴描述(用最直接的方式接近目标节点)
- 节点测试(用于筛选节点位置和名称)
- 节点描述(用于筛选节点的属性和子节点特征)
一般情况下,我们使用简写后的语法。虽然完整的轴描述是一种更加贴近人类语言,利用自然语言的单词和语法来书写的描述方式,但是相比之下也更加罗嗦。
简写后的语法
最简单的XPath如下:
/A/B/C
在这里选择所有符合规矩的C节点:C节点必须是B的子节点(B/C
),同时B节点必须是A的子节点(A/B
),而A是这个XML文档的根节点(/A
)。此时的这种描述法类似于磁盘中文件的路径,从盘符开始顺着一级一级的目录最终找到文件。
这里还有一个复杂一些的例子,包含了全部构成成分(请详细的看):
A//B/*[1]
此时选择的元素是:在B节点下的第一个节点(B/*[1]
),不论节点的名称如何(*
);而B节点必须出现在A节点内,不论和A节点之间相隔几层节点(//B
);与此同时A节点还必须是当前节点的子节点(A
,前边没有/
)。
轴描述语法
坐标 | 名称 | 说明 | 缩写语法 |
---|---|---|---|
child | 子节点 | 比自身节点深度大的一层的节点,且被包含在自身之内 | 默认,不需要 |
attribute | 属性 | @ |
|
descendant | 子孙节点 | 比自身节点深度大的节点,且被包含在自身之内 | 不提供 |
descendant-or-self | 自身引用及子孙节点 | // |
|
parent | 父节点 | 比自身节点深度小一层的节点,且包含自身 | .. |
ancestor | 祖先节点 | 比自身节点深度小的节点,且包含自身 | 不提供 |
ancestor-or-self | 自身引用及祖先节点 | 不提供 | |
following | 下文节点 | 按纵轴视图,在此节点后的所有完整节点,即不包含其祖先节点 | 不提供 |
preceding | 前文节点 | 按纵轴视图,在此节点前的所有完整节点,即不包含其子孙节点 | 不提供 |
following-sibling | 下一个同级节点 | 不提供 | |
preceding-sibling | 上一个同级节点 | 不提供 | |
self | 自己 | . |
|
namespace | 名称空间 | 不提供 |
选取节点
表达式 | 描述 |
---|---|
nodename | 选取此节点的所有子节点。 |
/ | 从根节点选取。 |
// | 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。 |
. | 选取当前节点。 |
.. | 选取当前节点的父节点。 |
@ | 选取属性。 |
节点测试
节点测试包括特定节点名或者更一般的表达式。至于XML里命名空间前缀gs
已定义的文件,//gs:enquiry
将找到所有在那命名空间里enquiry
的节点。
其他节点格式:
comment()
寻找XML注释节点,例如
<!-- 注释 -->
text()
寻找某点的文字型别,例如
hello
于<k>hello</k>
node()
寻找所有点
节点描述
节点描述为一个逻辑真假表达式,任何真假判断表达式都可在节点后方括号里表示,这条件必须在XPath处理这个节点前先被满足。在某一步骤可有多少个描述并没有限制。
范例如下: //a[@href='index.html']
,这将检查元素a
有没有href
属性,并且该它的值是index.html
。
复杂一些的范例如下:
//a[@href='index.html'][../div/@class='header']/@target
或
//a[@href='index.html'][name(..)='div'][../@class='header']/@target
此例将会选择符合条件的元素a
的target
属性。 要求元素a
:
- 具有属性
href
且值为index.html
; - 并且元素
a
具有父元素div
; - 并且父元素(
div
)其自身具备class
属性,值为header
。
小试牛刀
使用text() 获取 h1、p标签中的文本内容。
1 |
|
获取h1、p标签里面的内容
//h1/text() >> 我的第一个标题
//p/text() >> 我的第一个段落。
使用text() 获取 div id = main h1、p标签中的文本内容。
1 |
|
获取不同节点h1、p标签里面的内容
//div[@id=’main’]/h1/text() >> 我的第二个标题
//div[@id=’main’]/p/text() >> 我的第二个段落。
//div[@id=’main’]/h1/text() >> 我的第二个标题
//div[@id=’main’]/p/text() >> 我的第二个段落。
//div[@id=’king’]/div/h1/text() >> 我的第三个标题
//div[@id=’king’]/div/p/text() >> 我的第三个段落。
获取第一个div内h1、p标签里面的内容,和第二个div内h1、p标签里面的内容。
1 |
|
获取相同节点h1、p标签里面的内容。
//div[1]/h1/text() >> 我的第二个标题
//div[1]/p/text() >> 我的第二个段落。
//div[2]/h1/text() >>我的第三个标题
//div[2]/p/text() >> 我的第三个段落。
获取ul中li title = 4的内容。
1 |
|
//ul/li[@title=’4’]/text() >> 4
END