使用 XPATH 搜索包含的文本
Posted
技术标签:
【中文标题】使用 XPATH 搜索包含的文本【英文标题】:Using XPATH to search text containing 【发布时间】:2010-09-19 19:33:16 【问题描述】:我使用XPather Browser 在 html 页面上检查我的 XPATH 表达式。
我的最终目标是在 Selenium 中使用这些表达式来测试我的用户界面。
我得到了一个 HTML 文件,其内容类似于:
我想选择一个文本包含字符串“ 
”的节点。
使用像“abc”这样的普通字符串没有问题。我使用类似于 //td[text()="abc"]
的 XPATH。
当我尝试使用像 //td[text()=" "]
这样的 XPATH 时,它什么也不返回。对带有“&
”的文本有特殊规定吗?
【问题讨论】:
您的实际 XSL 转换没有返回任何结果吗?还是只有 Xpather? 【参考方案1】:根据您提供的 HTML:
<tr>
<td>abc</td>
<td> </td>
</tr>
要使用字符串 &nbsp;
定位节点,您可以使用以下基于 xpath 的解决方案之一:
使用text()
:
"//td[text()='\u00A0']"
使用contains()
:
"//td[contains(., '\u00A0')]"
但是,理想情况下,您可能希望避免使用 NO-BREAK SPACE 字符并使用以下任一Locator Strategies:
使用父节点<tr>
和following-sibling
:
"//tr//following-sibling::td[2]"
使用starts-with()
:
"//tr//td[last()]"
使用前面的<td>
节点和following
node and
following-sibling`:
"//td[text()='abc']//following::td[1]"
参考
您可以在以下位置找到相关的详细讨论:
How to find an element which contains&nbsp;
using Selenium
tl;博士
Unicode Character 'NO-BREAK SPACE' (U+00A0)
【讨论】:
【参考方案2】:尝试使用十进制实体&#160;
而不是命名实体。如果这不起作用,您应该能够简单地使用unicode character for a non-breaking space 而不是&nbsp;
实体。
(注意:我没有在 XPather 中尝试过,但我确实在 Oxygen 中尝试过。)
【讨论】:
【参考方案3】:搜索&nbsp;
或仅搜索nbsp
- 你试过了吗?
【讨论】:
我知道这应该可行,但我不确定我发现了什么。 XPATH 中必须有一种方法来编码某种方式以匹配我正在寻找的内容。 也许我应该看看正则表达式。【参考方案4】:Selenium 背后的人OpenQA 似乎已经解决了这个问题。他们定义了一些变量来明确匹配空格。就我而言,我需要使用类似于 //td[text()="$nbsp"]
的 XPATH。
我在这里转载了 OpenQA 关于这个问题的文字(找到here):
HTML 自动规范化 元素内的空格,忽略 前导/尾随空格和转换 额外的空格、制表符和换行符 单一空间。当 Selenium 读取文本时 在页面之外,它试图 重复此行为,因此您可以 忽略中的所有制表符和换行符 您的 HTML 并根据 文本在浏览器中的外观 呈现。我们通过替换所有 不可见的空白(包括 不间断空格“
&nbsp;
”)与 单一空间。所有可见的换行符 (<br>
、<p>
和<pre>
格式化 新行)应该被保留。我们使用相同的规范化逻辑 HTML Selenese 测试用例的文本 表。这有许多 优点。首先,你不需要 查看页面的 HTML 源代码 弄清楚你的断言应该是什么 是; “
&nbsp;
”符号不可见 给最终用户,所以你不应该 写作时不得不担心他们 硒测试。 (你不需要把 测试用例中的“&nbsp;
”标记 在包含的字段上断言文本 "&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$nbspworld"]
.
【讨论】:
OpenQA 链接不再加载成功 我只想指出 $nbsp 在 Selenium 或 Chrome 开发工具中对我不起作用,\u00a0
也不是。对我有用的是在 mac Alt+Shift+Space
上输入一个不间断的空格。网络搜索在 Windows 上显示 Alt+0160
。【参考方案5】:
请记住,符合标准的 XML 处理器将用相应的字符替换除 XML 的五个标准引用(&amp;
、&gt;
、&lt;
、&apos;
、&quot;
)之外的任何实体引用在评估 XPath 表达式时,在目标编码中。鉴于这种行为,如果您想使用 XML 工具,PhiLho 和 jsulak 的建议是您的最佳选择。在 XPath 表达式中输入&#160;
时,应在应用 XPath 表达式之前将其转换为相应的字节序列。
【讨论】:
如果您在 XPather (GUI) 或 javascript 中尝试/使用 XPath(不自动替换实体,因为我们不在 XML 中),则不会。在其他 XML 环境(XSTL?)中的好建议。【参考方案6】:我无法使用 Xpather 获得匹配,但以下内容适用于 Microsoft 的 XML 记事本中的纯 XML 和 XSL 文件:
<xsl:value-of select="count(//td[text()=' '])" />
返回的值为 1,这是我的测试用例中的正确值。
但是,我确实必须在我的 XML 和 XSL 中使用以下语句将 nbsp 声明为一个实体:
<!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp " "> ]>
我不确定这是否对您有帮助,但我能够实际上使用 XPath 表达式找到 nbsp。
编辑:我的代码示例实际上包含字符 ' ' 但 JavaScript 语法高亮将其转换为空格字符。不要误导!
【讨论】:
您可以编辑您的代码示例,就像为我的问题中的示例所做的那样。用 替换您的 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->query("//p[text()=\"\xC2\xA0\"]");
@Bergory 这适用于 Protractor 和 Selenium 驱动程序以上是关于使用 XPATH 搜索包含的文本的主要内容,如果未能解决你的问题,请参考以下文章
Selenium XPath 合并跨越文本并查找包含子字符串的元素
如何使用 JUnit 断言元素包含 Selenium 中的文本