使用XPATH搜索包含的文本

时间:2008-10-29 15:00:31

标签: xml search xpath selenium

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

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

我收到了一个HTML文件,内容与此类似:

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

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

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

当我尝试像//td[text()="&nbsp;"]之类的XPATH时,它什么都不返回。关于带有“&”的文本是否有特殊规则?

8 个答案:

答案 0 :(得分:86)

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

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

  

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 :(得分:22)

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

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

使用特殊字符为我工作。

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

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

答案 2 :(得分:4)

尝试使用小数实体&#160;而不是命名实体。如果这不起作用,您应该只能使用unicode character for a non-breaking space而不是&nbsp;实体。

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

答案 3 :(得分:2)

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

答案 4 :(得分:2)

根据您提供的HTML:

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

要找到包含字符串 &nbsp; 的节点,可以使用以下基于的解决方案之一:

  • 使用text()

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

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

但是,理想情况下,您最好避免使用 NO-BREAK空格字符,并使用以下Locator Strategies之一:

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

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

    "//tr//td[last()]"
    
  • 使用前面的<td>节点和following node and跟随兄弟姐妹:

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

参考

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


tl;博士

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

答案 5 :(得分: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

修改:我的代码示例实际上包含字符'&amp; nbsp;',但JavaScript语法高亮显示将其转换为空格字符。不要误导!

答案 6 :(得分:0)

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

答案 7 :(得分:-1)

您可以使用Selenium WebDriver中的XPath包含,同级,祖先函数来定位没有任何唯一属性的元素。

有关更多详细信息,请阅读以下页面: https://www.guru99.com/using-contains-sbiling-ancestor-to-find-element-in-selenium.html