re:test()XPath到HtmlAgilityPack(获取匹配的regex内部的所有p标签)

c# html html-agility-pack xpath

我想要所有<p>=.+=</p>标签。正则表达式独立工作,没有<p>标签。

这是我的XPath: "//p[re:test(.,'^=.+=$', 'i')]""//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(),这意味着“内部文本”。


热门答案

显然HtmlAgilityPack不处理命名空间(不是我有一个)。所以我想出了这个黑客,

var pNodes = htmlDoc.DocumentNode.SelectNodes("//p")
    .Where(node => Regex.Match(node.InnerText, "^=.+=$").Success);

如果有一个HtmlAgilityPack解决方案,我很乐意听到它!




许可下: CC-BY-SA with attribution
不隶属于 Stack Overflow
这个KB合法吗? 是的,了解原因
许可下: CC-BY-SA with attribution
不隶属于 Stack Overflow
这个KB合法吗? 是的,了解原因