使用 XPATH 搜索包含的文本

Posted

技术标签:

【中文标题】使用 XPATH 搜索包含的文本【英文标题】:Using XPATH to search text containing   【发布时间】:2010-09-19 19:33:16 【问题描述】:

我使用XPather Browser 在 html 页面上检查我的 XPATH 表达式。

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

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

abc  

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

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

当我尝试使用像 //td[text()=" "] 这样的 XPATH 时,它什么也不返回。对带有“&”的文本有特殊规定吗?

【问题讨论】:

您的实际 XSL 转换没有返回任何结果吗?还是只有 Xpather? 【参考方案1】:

根据您提供的 HTML:

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

要使用字符串 &amp;nbsp; 定位节点,您可以使用以下基于 xpath 的解决方案之一:

使用text()

"//td[text()='\u00A0']"

使用contains()

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

但是,理想情况下,您可能希望避免使用 NO-BREAK SPACE 字符并使用以下任一Locator Strategies:

使用父节点&lt;tr&gt;following-sibling

"//tr//following-sibling::td[2]"

使用starts-with()

"//tr//td[last()]"

使用前面的&lt;td&gt; 节点和followingnode andfollowing-sibling`:

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

参考

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

How to find an element which contains &amp;nbsp; using Selenium

tl;博士

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

【讨论】:

【参考方案2】:

尝试使用十进制实体&amp;#160; 而不是命名实体。如果这不起作用,您应该能够简单地使用unicode character for a non-breaking space 而不是&amp;nbsp; 实体。

(注意:我没有在 XPather 中尝试过,但我确实在 Oxygen 中尝试过。)

【讨论】:

【参考方案3】:

搜索&amp;nbsp; 或仅搜索nbsp - 你试过了吗?

【讨论】:

我知道这应该可行,但我不确定我发现了什么。 XPATH 中必须有一种方法来编码某种方式以匹配我正在寻找的内容。 也许我应该看看正则表达式。【参考方案4】:

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

我在这里转载了 OpenQA 关于这个问题的文字(找到here):

HTML 自动规范化 元素内的空格,忽略 前导/尾随空格和转换 额外的空格、制表符和换行符 单一空间。当 Selenium 读取文本时 在页面之外,它试图 重复此行为,因此您可以 忽略中的所有制表符和换行符 您的 HTML 并根据 文本在浏览器中的外观 呈现。我们通过替换所有 不可见的空白(包括 不间断空格“&amp;nbsp;”)与 单一空间。所有可见的换行符 (&lt;br&gt;&lt;p&gt;&lt;pre&gt; 格式化 新行)应该被保留。

我们使用相同的规范化逻辑 HTML Selenese 测试用例的文本 表。这有许多 优点。首先,你不需要 查看页面的 HTML 源代码 弄清楚你的断言应该是什么 是; “&amp;nbsp;”符号不可见 给最终用户,所以你不应该 写作时不得不担心他们 硒测试。 (你不需要把 测试用例中的“&amp;nbsp;”标记 在包含的字段上断言文本 "&amp;nbsp;".) 你也可以多放 Selenese 中的换行符和空格 &lt;td&gt; 标签;因为我们使用相同的 测试用例的规范化逻辑 正如我们对文本所做的那样,我们可以确保 该断言和提取的文本 将完全匹配。

这在 那些罕见的场合,当你真的 想要/需要插入额外的空格 在你的测试用例中。例如,你 可能需要在字段中键入文本,例如 这个:“foo”。但如果你只是 写&lt;td&gt;foo &lt;/td&gt; 在你的 Selenese 测试用例,我们将替换您的 额外的空格只有一个空格。

这个问题有一个简单的解决方法。 我们在 Selenese 中定义了一个变量, $space,其值为单个 空间。您可以使用$space 插入一个不会出现的空格 自动修剪,如下所示: &lt;td&gt;foo$space$space$space&lt;/td&gt;。 我们还包括了一个变量 $nbsp,您可以使用它来插入 一个不间断的空间。

请注意,XPath 不会规范化 以我们的方式留白。如果你需要 像写一个 XPath //div[text()="hello world"] 但是 链接的 HTML 真的是 “hello&amp;nbsp;world”,你需要 插入一个真正的“&amp;nbsp;”到你的 Selenese 测试用例使其匹配, 像这样: //div[text()="hello$nbspworld"].

【讨论】:

OpenQA 链接不再加载成功 我只想指出 $nbsp 在 Selenium 或 Chrome 开发工具中对我不起作用,\u00a0 也不是。对我有用的是在 mac Alt+Shift+Space 上输入一个不间断的空格。网络搜索在 Windows 上显示 Alt+0160【参考方案5】:

请记住,符合标准的 XML 处理器将用相应的字符替换除 XML 的五个标准引用(&amp;amp;&amp;gt;&amp;lt;&amp;apos;&amp;quot;)之外的任何实体引用在评估 XPath 表达式时,在目标编码中。鉴于这种行为,如果您想使用 XML 工具,PhiLho 和 jsulak 的建议是您的最佳选择。在 XPath 表达式中输入&amp;#160; 时,应在应用 XPath 表达式之前将其转换为相应的字节序列。

【讨论】:

如果您在 XPather (GUI) 或 javascript 中尝试/使用 XPath(不自动替换实体,因为我们不在 XML 中),则不会。在其他 XML 环境(XSTL?)中的好建议。【参考方案6】:

我无法使用 Xpather 获得匹配,但以下内容适用于 Microsoft 的 XML 记事本中的纯 XML 和 XSL 文件:

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

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

但是,我确实必须在我的 XML 和 XSL 中使用以下语句将 nbsp 声明为一个实体:

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

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

编辑:我的代码示例实际上包含字符 ' ' 但 JavaScript 语法高亮将其转换为空格字符。不要误导!

【讨论】:

您可以编辑您的代码示例,就像为我的问题中的示例所做的那样。用 &nbsp; 替换您的 nbsp 实体。【参考方案7】:

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

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

使用特殊字符为我工作。

据我了解,XPath 1.0 标准不处理转义 Unicode 字符。 XPath 2.0 中似乎有这样的功能,但看起来 Firefox 不支持它(或者我误解了一些东西)。所以你必须与本地代码页有关。丑,我知道。

实际上,标准似乎依赖于使用 XPath 的编程语言来提供正确的 Unicode 转义序列......所以,不知何故,我做对了。

【讨论】:

在 Firefox 2 中使用 Xpather 1.4.1,//td[text()=' '] 没有结果。 对不起。它对我不起作用。我的最终目标是在 Selenium 中使用它来测试我的 Web 界面。 Selenium 本身将测试表达式保存在 XML 结构中,Alt Windows 键入似乎在路上丢失了。另外,我的  在 XML 中以 a 形式返回。 扎克,正如我所写,你必须用 Alt+0160 (在数字键盘上)产生的字符替换两个引号之间的空格。 也可以成功地使用 php$col = $xpath-&gt;query("//p[text()=\"\xC2\xA0\"]"); @Bergory 这适用于 Protractor 和 Selenium 驱动程序

以上是关于使用 XPATH 搜索包含的文本的主要内容,如果未能解决你的问题,请参考以下文章

XPath 文本/替换以查找可能包含软连字符的文本

如何在打印(xpath)之前检查文本是不是包含特定字符?

Selenium XPath 合并跨越文本并查找包含子字符串的元素

如何使用 JUnit 断言元素包含 Selenium 中的文本

按文本查找元素并获取xpath - selenium webdriver junit

如何指定 XPath 以生成包含与其父元素属性连接的元素文本的列表