当前位置:首页 > Windows程序 > 正文

C#操作xml SelectNodes,SelectSingleNode总是返回NULL 与 xPath 介绍

2021-03-20 Windows程序

最近,我做了很多工作来实现一个同时支持XPath和CSS 3的解析器,令我惊讶的是:它们俩在某些方面上非常相似,而在另一些方面上又完全不同.不同的地方有,CSS是用来配合HTML工作的,可以使用#id来根据ID获取元素,以及使用.class来根据class获取元素.这些用XPath实现的话都不会那么简洁,反过来呢,XPath可以使用..来返回到DOM树的上层节点中,还可以使用foo[bar]来获取到一个拥有bar子元素的foo元素.CSS选择器完全做不到这些,总结一下就是,和XPath比起来,CSS选择器通常都比较短小,但可惜的是不够强大.

我认为将这两种选择器的写法做一个比较是很有价值的.

目标CSS 3XPath
所有元素   *   //*  
所有的P元素   p   //p  
所有的p元素的子元素   p > *   //p/*  
根据ID获取元素   #foo   //*[@id=‘foo‘]  
根据Class获取元素   .foo                                  //*[contains(@class,‘foo‘)]  
拥有某个属性的元素   *[title]   //*[@title]  
所有P元素的第一个子元素   p > *:first-child   //p/*[0]  

所有拥有子元素a的P元素

  无法实现   //p[a]  
下一个兄弟元素   p + *   //p/following-sibling::*[0]  

从语法上看,我非常惊讶这两种选择器在某些情况下的相似性,尤其是‘>‘和‘/‘两者之间.虽然他们并不总是有着相同的功能(XPath中要取决于正在使用的轴),但通常情况下他们指的都是某个父元素的子元素.还有,空白符‘ ‘和‘//‘都意味着当前元素的所有后代元素.最后是星号‘*‘,类似于通配符,表示所有元素,而不管是哪种标签名.

1 这个写法其实不正确,因为它不光会匹配到我们想要的‘foo bar‘,还会意外的匹配到‘foobar‘.正确的写法可能会非常复杂,可能会需要用到多个表达式才能完成.

下面是译者注:

上表中错误的XPath:

//*[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结合起来使用.

jQuery.getScript("http://wicked-good-xpath.googlecode.com/files/wgxpath.install.js").success(function () { //加载库文件
wgxpath.install(); //安装XPath支持
jQuery.xpath = function (xpath) { var elements = []; //用来存储XPath选择到的元素
var xpathResult = document.evaluate(xpath, document, null, 6, null); for (var i = 0; i < xpathResult.snapshotLength; i++) { elements.push(xpathResult.snapshotItem(i)); } return jQuery(elements); //传给jQuery工厂方法,返回jQuery对象
} })

这样就能通过$.xpath()静态方法来选择元素了,该方法返回的也是一个jQuery对象,和使用$()没什么差别.本页面已经加载了这个脚本,你可以现在打开控制台试验一下$.xpath方法.

那我们有了CSS选择器,为什么还要用XPath呢,答案是:有些时候,XPath更强大一点.比如:

温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/64329.html