XPath在链接中按文本选择,链接也包含i

时间:2013-12-15 21:38:19

标签: html xpath

我正在尝试使用XPath根据链接文本在链接(标签)列表中查找链接。问题是他们也有图标(目前隐藏),所以简单地使用text()是不匹配的。

我试过了:

  • //ul[contains(@class, 'nav-tabs')]/li/a[text()='Details']
  • //ul[contains(@class, 'nav-tabs')]/li/a[normalize-space(text())='Details']

但都找不到“详细信息”标签。只需执行//ul[contains(@class, 'nav-tabs')]/li/a确实可以获取所有链接,然后我可以在其中看到<i>Details文本,但我无法获得“详细信息”链接。

我想避免使用contains(),因为我担心如果一个单词在一个更大的单词中,我们将有两个可以匹配的标签,所以我想要完全匹配它。

HTML:

<ul class="nav nav-tabs">
    <li class="active">
        <a href="#s52ae1defa2b1e_1" data-toggle="tab">
            <i class="icon-exclamation-sign has-errors hide"></i>
            Details
        </a>
    </li>
    <li class="">
        <a href="#s52ae1defa2b1e_2" data-toggle="tab">
            <i class="icon-exclamation-sign has-errors hide"></i>
            Description
        </a>
    </li>
    <li class="">
        <a href="#s52ae1defa2b1e_3" data-toggle="tab">
            <i class="icon-exclamation-sign has-errors hide"></i>
            SEO
        </a>
    </li>
</ul>

1 个答案:

答案 0 :(得分:2)

您可以使用//ul[contains(@class, 'nav-tabs')]/li/a[normalize-space(.)='Details']

//ul[contains(@class, 'nav-tabs')]/li/a[text()[normalize-space(.)='Details']]

normalize-space()期望字符串作为参数,因此上下文节点.将转换为字符串。在这种情况下,a元素内的文本表示。

您甚至可以省略上下文节点并使用//ul[contains(@class, 'nav-tabs')]/li/a[normalize-space()='Details']

来自the XPath 1.0 docs

  

normalize-space函数返回带有空格的参数字符串,该空格通过剥离前导和尾随空格并用空格替换空格字符序列来规范化。空格字符与XML生成中允许的空格字符相同。如果省略该参数,则默认为转换为字符串的上下文节点,换句话说,是上下文节点的字符串值。


OP评论后的更多解释:

text()是一个节点测试(参见this link),但没有给出上下文节点的字符串值,它是XPath表达式中的一个测试

  

对于任何文本节点,节点测试文本()都为true。

normalize-space(text())确实会返回一个字符串,但在你的情况下是一个空字符串。节点集参数text()将匹配上下文节点的所有文本子节点,将转换为字符串值,但仅考虑节点集中的第一个节点。见the string() function description

  

通过在文档顺序的节点集中返回节点的字符串值,将节点集转换为字符串。如果节点集为空,则返回空字符串。

这也适用于normalize-space()

因此,如果您使用normalize-space(text()),则会在a上下文中获得一个空字符串。

您可以使用示例HTML在http://www.freeformatter.com/xpath-tester.html上使用//ul[contains(@class, 'nav-tabs')]/li/a/text()对此进行验证。你会得到

Text=''   <-- this will be used in //li/a[normalize-space(text())...
Text='Details'
Text=''
Text='Description'
Text=''
Text='SEO'

你可以看到normalize-space(//ul[contains(@class, 'nav-tabs')]/li/a/text())返回一个空字符串。

但是,如果您使用normalize-space(.)normalize-space()将从前导和尾随空格中删除的字符串值将是上下文的字符串值节点,a

  

元素节点的字符串值是文档顺序中元素节点的所有文本节点后代的字符串值的串联。