使用XPATH搜索包含 的文本


120

我使用XPather浏览器检查HTML页面上的XPATH表达式。

我的最终目标是在Selenium中使用这些表达式来测试用户界面。

我得到了一个HTML文件,其内容类似于以下内容:

<tr>
  <td> abc </ td>
  <td>&nbsp; </ td>
</ tr>

我想选择一个文本包含字符串“ &nbsp;” 的节点。

使用“ abc”之类的普通字符串不会有问题。我使用类似于的XPATH //td[text()="abc"]

当我尝试使用类似的XPATH时,//td[text()="&nbsp;"]不会返回任何内容。关于带有“ &”的文本是否有特殊规定?


您实际的XSL转换不会返回任何内容吗?还是只有Xpather?
Zack The Human

Answers:


89

似乎Selenium背后的家伙OpenQA已经解决了这个问题。他们定义了一些变量以明确匹配空白。就我而言,我需要使用类似于的XPATH //td[text()="${nbsp}"]

我在这里转载自OpenQA有关这一问题(找到的文本在这里):

HTML会自动规范元素内的空格,而忽略前导/尾随空格,并将多余的空格,制表符和换行符转换为单个空格。当Selenium从页面中读取文本时,它将尝试复制此行为,因此您可以忽略HTML中的所有选项卡和换行符,并根据呈现时文本在浏览器中的外观进行断言。为此,我们将所有不可见的空格(包括不间断空格“ &nbsp;”)替换为一个空格。所有可见的换行符(<br><p><pre>格式化的新行)都应保留。

我们对HTML Selenese测试用例表的文本使用相同的规范化逻辑。这具有许多优点。首先,您无需查看页面的HTML源代码即可确定您的断言应该是什么;“ &nbsp;”符号对于最终用户是不可见的,因此您在编写Selenese测试时不必担心它们。(您不需要&nbsp;在测试用例中放置标记,以将assertText包含在包含“ &nbsp;” 的字段上。)您还可以在Selenese <td>标记中添加多余的换行符和空格 ;由于我们在测试用例上使用与在文本上相同的规范化逻辑,因此我们可以确保断言和提取的文本将完全匹配。

在极少数情况下,当您确实想要/需要在测试用例中插入额外的空格时,这会带来一些问题。例如,您可能需要在如下字段中输入文本:“ foo ”。但是,如果您只是<td>foo </td>在Selenese测试用例中编写代码,我们将用一个空格替换您的多余空格。

此问题有一个简单的解决方法。我们用Selenese定义了一个变量 ${space},其值是一个空格。您可以使用${space}插入不会自动修剪的空间,如下所示: <td>foo${space}${space}${space}</td>。我们还包含了一个变量${nbsp},您可以使用该变量 插入一个不间断的空格。

请注意,XPath 不会像我们那样规范空白。如果您需要编写类似XPath的代码, //div[text()="hello world"]但链接的HTML确实是“ hello&nbsp;world”,则需要&nbsp;在Selenese测试用例中插入一个真实的“ ”以使其匹配,例如: //div[text()="hello${nbsp}world"]


1
OpenQA链接不再成功加载
kjosh

1
我只想指出$ {nbsp}在Selenium或Chrome开发工具中对我不起作用,也不是\u00a0。对我有用的是在mac上键入一个不间断的空格Alt+Shift+Space。网络搜索Alt+0160在Windows上说。
犬儒主义

25

我发现我可以通过在Windows中在两个引号之间输入Alt + 0160来输入硬编码的不间断空格(U + 00A0)来进行匹配...

//table[@id='TableID']//td[text()=' ']

用特殊字符为我工作。

据我了解,XPath 1.0标准无法处理转义的Unicode字符。XPath 2.0中似乎有针对该功能的功能,但似乎Firefox不支持它(或者我误解了)。因此,您必须处理本地代码页。丑,我知道。

实际上,看起来该标准依赖于使用XPath的编程语言来提供正确的Unicode转义序列...因此,以某种方式,我做了正确的事情。


在Firefox 2中使用Xpather 1.4.1,// td [text()='']不会产生任何结果。
Zack The Human

抱歉。它对我不起作用。我的最终目标是在Selenium中使用它来测试Web界面。Selenium本身将测试表达式保存在XML结构中,而Alt Windows的输入似乎会丢失。另外,我的&#160; 以XML形式返回。
Bergeroy

正如我所写,Zack,您必须用Alt + 0160(在数字小键盘上)产生的字符替换两个引号之间的空格。
PhiLho's

4
也成功地使用了PHP:$col = $xpath->query("//p[text()=\"\xC2\xA0\"]");
hakre 2011年

@Bergory可以将量角器与硒驱动程序一起使用
Damian Green


2

请记住,一个符合标准的XML处理器将已经取代了比XML的五个标准以外的其他任何实体引用(&amp;&gt;&lt;&apos;&quot;与XPath表达式的计算时间与目标编码对应的字符)。考虑到这种行为,如果您想使用XML工具,PhiLho和jsulak的建议是必经之路。输入&#160;XPath表达式时,应在应用XPath表达式之前将其转换为相应的字节序列。


1
如果您在XPather(GUI)或JavaScript中尝试/使用XPath,则不会(由于我们不在XML中,因此无法自动替换实体)。在其他XML环境(XSTL?)中的良好建议。
披披,

1

我无法使用Xpather进行匹配,但是以下代码适用于Microsoft的XML记事本中的纯XML和XSL文件:

<xsl:value-of select="count(//td[text()='&nbsp;'])" />

返回的值为1,这是我的测试用例中的正确值。

但是,我确实必须使用以下方法将nbsp声明为XML和XSL中的实体:

<!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp "&#160;"> ]>

我不确定这是否对您有帮助,但是我实际上可以使用XPath表达式找到nbsp

编辑:我的代码示例实际上包含字符'&nbsp;' 但是JavaScript语法突出显示部分会将其转换为空格字符。不要误导!


您可以像对我的问题中的示例所做的那样编辑代码示例。将您的nbsp实体替换为&amp; nbsp;。
Bergeroy

1

搜索&nbsp;还是仅搜索nbsp-您是否尝试过?


我知道这应该可行,但是我不确定我能找到什么。XPATH中必须有一种编码某种方式来匹配我要寻找的内容的方法。
Bergeroy,

也许我应该看一下正则表达式。
Bergeroy

1

根据您提供的HTML:

<tr>
  <td>abc</td>
  <td>&nbsp;</td>
</tr>

要使用字符串查找节点,&nbsp;可以使用以下任一方法 基于解决方案:

  • 使用text()

    "//td[text()='\u00A0']"
  • 使用contains()

    "//td[contains(., '\u00A0')]"

但是,理想情况下,您可能希望避免使用NO-BREAK SPACE字符,并使用以下两种定位策略之一

  • 使用父<tr>节点和following-sibling

    "//tr//following-sibling::td[2]"
  • 使用starts-with()

    "//tr//td[last()]"
  • 使用先行<td>节点和followingnode and后继节点:

    "//td[text()='abc']//following::td[1]"

参考

您可以在以下位置找到相关的详细讨论:


tl; 博士

Unicode字符'NO-BREAK SPACE'(U + 00A0)


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.