黄聪:HtmlAgilityPack中SelectSingleNode的XPath和CSS选择器
XPath和CSS选择器
原文:http://ejohn.org/blog/xpath-css-selectors
最近,我做了很多工作来实现一个同时支持XPath和CSS 3的解析器,令我惊讶的是:它们俩在某些方面上非常相似,而在另一些方面上又完全不同.不同的地方有,CSS是用来配合HTML工作的,可以使用#id来根据ID获取元素,以及使用.class来根据class获取元素.这些用XPath实现的话都不会那么简洁,反过来呢,XPath可以使用..来返回到DOM树的上层节点中,还可以使用foo[bar]来获取到一个拥有bar子元素的foo元素.CSS选择器完全做不到这些,总结一下就是,和XPath比起来,CSS选择器通常都比较短小,但可惜的是不够强大.
我认为将这两种选择器的写法做一个比较是很有价值的.
| 目标 | CSS 3 | XPath |
|---|---|---|
| 所有元素 | * | //* |
| 所有的P元素 | p | //p |
| 所有的p元素的子元素 | p > * | //p/* |
| 根据ID获取元素 | #foo | //*[@id='foo'] |
| 根据Class获取元素 | .foo | //*[contains(@class,'foo')] 1 |
| 拥有某个属性的元素 | *[title] | //*[@title] |
| 所有P元素的第一个子元素 | p > *:first-child | //p/*[0] |
|
所有拥有子元素a的P元素 |
无法实现 | //p[a] |
| 下一个兄弟元素 | p + * | //p/following-sibling::*[0] |
从语法上看,我非常惊讶这两种选择器在某些情况下的相似性,尤其是'>'和'/'两者之间.虽然他们并不总是有着相同的功能(XPath中要取决于正在使用的轴),但通常情况下他们指的都是某个父元素的子元素.还有,空白符' '和'//'都意味着当前元素的所有后代元素.最后是星号'*',类似于通配符,表示所有元素,而不管是哪种标签名.
1 这个写法其实不正确,因为它不光会匹配到我们想要的'foo bar',还会意外的匹配到'foobar'.正确的写法可能会非常复杂,可能会需要用到多个表达式才能完成.
下面是译者注:
//*[contains(@class,'foo')]
我实现的写法是:
//*[@class='foo' or contains(@class,' foo ') or starts-with(@class,'foo ') or substring(@class,string-length(@class)-3)=' foo']
比起CSS的.foo,真的是好复杂,我来解释一下,一个元素的class属性中如果包含'foo',可能有四种情况,列出表来是这样的:
| class="foo" | //*[@class='foo'] | class属性只有一个值foo |
| class="foobar foo bar" | //*[@class=' foo '] | class属性值中,foo在其他两边的值的中间 |
|
class="foo bar" |
//*[starts-with(@class,'foo ')] | class属性值中,foo在最左边 |
| class="bar foo" | //*[substring(@class,string-length(@class)-3)=' foo'] | class属性值中,foo在最右边,XPath1.0中没有ends-with函数,2.0有,现在浏览器实现的都是1.0 |
那么我们能在网页开发中用上XPath吗?最初,jQuery是支持XPath选择器的,但后来,由于效率问题,jQuery放弃了对XPath的支持.刚好,谷歌在上个月发布了Wicked Good XPath,这是一个DOM Level 3 XPath规范的纯JavaScript实现,也是目前同类实现中最快的,我们可以把这个脚本和jQuery结合起来使用.
黄聪:HtmlAgilityPack中SelectSingleNode的XPath和CSS选择器的更多相关文章
- Selenium自动化中DOM,XPATH,CSS定位Web页面对象的优劣性分析
加速IE浏览器自动化执行效率:Selenium自动化中DOM,XPATH,CSS定位Web页面对象的优劣性分析 1.技术背景 在Web应用中,用户通过键盘在输入框中输入值和鼠标点击按钮,链 ...
- 正则表达式(特殊字符)/Xpath语法/CSS选择器
正则表达式(特殊字符) ^ 开头 '^b.*'----以b开头的任意字符 $ 结尾 '^b.*3$'----以b开头,3结尾的任意字符 * 任意长度(次数),≥0 ? 非贪婪模式,非贪婪模式尽可能少的 ...
- xpath和CSS选择器
.content是二进制 用来处理声音.图片.视频 .text是文本 xpath语法: /一层层查找 //不固定位置 //title/text() @选取属性 [@href]和[@href=''] . ...
- xpath和css选择器对比
基本语法对比 都可以在html中提取内容,但xpath可以提取xml的内容.
- XPath、CSS 选择器 -学习地址
http://www.w3school.com.cn/cssref/css_selectors.asp http://www.w3school.com.cn/xpath/xpath_syntax.as ...
- 黄聪:C#操作xml SelectNodes,SelectSingleNode通过 xPath 定位class包含Contains的DIV
一. SelectNodes,SelectSingleNode总是返回NULL 下面以一个简单的xml为例: <?xml version="1.0"?> <mes ...
- Python网络爬虫四大选择器(正则表达式、BS4、Xpath、CSS)总结
一.正则表达式 正则表达式为我们提供了抓取数据的快捷方式.虽然该正则表达式更容易适应未来变化,但又存在难以构造.可读性差的问题.当在爬京东网的时候,正则表达式如下图所示: 此外 ,我们都知道,网页时常 ...
- 【转】黄聪:HtmlAgilityPack教程案例
[转]黄聪:HtmlAgilityPack教程案例 HtmlAgilityPack中的HtmlNode类与XmlNode类差不多,提供的功能也大同小异.下面来看看该类提供功能. 一.静态属性 publ ...
- 黄聪:C#类似Jquery的html解析类HtmlAgilityPack基础类介绍及运用
Html Agility Pack下载地址:http://htmlagilitypack.codeplex.com/ Html Agility Pack 源码中的类大概有28个左右,其实不算一个很复杂 ...
随机推荐
- easyUI参数传递Long型8100131457085857579980953变成8.100131457085857e 24的问题,如下可以解决
function addOptBtn(val, row, index) { var ht = "<a href='${pageContext.request.contextPath}/ ...
- HDU 1863
http://acm.hdu.edu.cn/showproblem.php?pid=1863 复习考研练练写Prim,第一次写,乱搞的,有点难看 邻接表+堆 #include <iostream ...
- 项目里的jquery.min.js错误
项目里的jquery.min.js报一系列 - Missing semicolon - Missing semicolon - Missing semicolon - Missing semicolo ...
- 【JS】点击目标外事件与IFRAM自适应高度
一.点击目标外事件 $(document).mouseup(function(e){ var _con = $('.dropdown-multiSelect-list'); // 设置目标区域 if( ...
- imshow() displays a white image for a grey image
Matlab expects images of type double to be in the 0..1 range and images that are uint8 in the 0..255 ...
- hibernate persist update 方法没有正常工作(不保存数据,不更新数据)
工程结构 问题描述 在工程中通过spring aop的方式配置事务,使用hibernate做持久化.在代码实现中使用hibernate persit()方法插入数据到数据库,使用hibernate u ...
- Lua Coroutine详解
协同程序与线程差不多,也就是一条执行序列,拥有自己独立的栈,局部变量和指令指针,同时又与其它协同程序共享全局变量和其它大部分东西.线程与协同程序的主要区别在于,一个具有多线程的程序可以同时运行几个线程 ...
- iconv 失败
网上的都是这样用的 代码如下: $content = iconv("utf-8","gb2312",$content); 这样做其实也 ...
- JS对象实现随机满天小星星实例
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 过滤emoji表情
str=str.replace(/\ud83c[\udf00-\udfff]|\ud83d[\udc00-\ude4f]|\ud83d[\ude80-\udeff]/g, "");