问题描述
|
我想要所有的
<p>=.+=</p>
标签。正则表达式可以独立工作,没有<p>
标签。
这是我的XPath:\"//p[re:test(.,\'^=.+=$\',\'i\')]\"
但是插入时出现异常,
HtmlNodeCollection pNodes = htmlDoc.DocumentNode.SelectNodes(\"//p[re:test(.,\'i\')]\");
例外是:
命名空间管理器或XsltContext
需要。该查询有一个前缀,
变量或用户定义的函数。
编辑:HTML由FCKEditor生成,并且没有定义名称空间。我需要为此设置一些功能吗?
HTML:
<p><style type=\"text/css\">
h2 a { color: black; }</style></p>
<p>----</p>
<h2>test <a href=\"http://searisen.com\">link</a></h2>
<p>== heading 2 ==</p>
<p>----</p>
<p>=== heading [http://searisen.com SeaRisen.com] ===</p>
解决方法
您遇到的错误是由于表达式
re:test
使用了名为test
的XPATH函数(在前缀为re
的命名空间中声明),而XSLT上下文未知。
我不知道您从何处获得该表达式,但这不是标准的,因此在Html Agility Pack上下文中没有任何意义:-)
有关深入的说明,请参见此处的精彩文章:向XPath添加自定义函数。请注意,您可以使用这些技术使其工作。
也就是说,这是一个“纯” HTML Agility Pack / XPATH实现:
var pNodes = htmlDoc.DocumentNode.SelectNodes(\"//p[text()=\'=.+=\']\");
它使用一个过滤器(在[和]之间)和标准的XPATH函数text()表示\“ inner text \”。
,显然,HtmlAgilityPack不处理名称空间(不是我拥有的名称空间)。所以我想出了这个办法
var pNodes = htmlDoc.DocumentNode.SelectNodes(\"//p\")
.Where(node => Regex.Match(node.InnerText,\"^=.+=$\").Success);
如果有HtmlAgilityPack解决方案,我很想听听!
,呼应Simon Mourier所说,re:test()函数不是XPath的核心函数。它可以在Calibre的XPath功能集中(http://manual.calibre-ebook.com/xpath.html#term-re-test)中使用,但这是非标准扩展。除了Calibre之外,我还没有其他系统可以公开re:test()函数。
有关核心XPath功能和XSLT扩展功能的完整摘要,请参见https://developer.mozilla.org/en-US/docs/Web/XPath/Functions