Usando XPATH para pesquisar texto contendo o & nbsp;


120

Eu uso o XPather Browser para verificar minhas expressões XPATH em uma página HTML.

Meu objetivo final é usar essas expressões no Selenium para testar minhas interfaces de usuário.

Eu tenho um arquivo HTML com um conteúdo semelhante a este:

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

Desejo selecionar um nó com um texto que contenha a string " &nbsp;".

Com uma string normal como "abc", não há problema. Eu uso um XPATH semelhante ao //td[text()="abc"].

Quando tento com um XPATH como //td[text()="&nbsp;"]ele não retorna nada. Existe uma regra especial para textos com " &"?


Sua transformação XSL real não retorna nada? Ou apenas Xpather?
Zack The Human

Respostas:


89

Parece que o OpenQA , que está por trás do Selenium, já abordou esse problema. Eles definiram algumas variáveis ​​para corresponder explicitamente a espaços em branco. No meu caso, preciso usar um XPATH semelhante ao //td[text()="${nbsp}"].

Reproduzi aqui o texto do OpenQA sobre esse problema (encontrado aqui ):

O HTML normaliza automaticamente o espaço em branco dentro dos elementos, ignorando os espaços iniciais / finais e convertendo espaços extras, guias e novas linhas em um único espaço. Quando o Selenium lê o texto da página, ele tenta duplicar esse comportamento, para que você possa ignorar todas as guias e novas linhas do seu HTML e fazer afirmações com base na aparência do texto no navegador quando renderizado. Fazemos isso substituindo todo o espaço em branco não visível (incluindo o espaço sem quebra " &nbsp;") por um único espaço. Todas as novas linhas visíveis ( <br>, <p>e <pre>novas linhas formatadas) devem ser preservadas.

Usamos a mesma lógica de normalização no texto das tabelas de casos de teste HTML Selenese. Isso tem várias vantagens. Primeiro, você não precisa consultar a fonte HTML da página para descobrir quais devem ser suas afirmações; os &nbsp;símbolos " " são invisíveis para o usuário final e, portanto, você não precisa se preocupar com eles ao escrever os testes Selenese. (Você não precisa colocar &nbsp;marcadores " " no seu caso de teste para afirmarText em um campo que contém " &nbsp;".) Você também pode colocar novas linhas e espaços extras nas <td>tags Selenese ; como usamos a mesma lógica de normalização no caso de teste que usamos no texto, podemos garantir que as asserções e o texto extraído correspondam exatamente.

Isso cria um problema nas raras ocasiões em que você realmente deseja / precisa inserir espaço em branco extra no seu caso de teste. Por exemplo, pode ser necessário digitar texto em um campo como este: " foo ". Mas se você simplesmente escrever <td>foo </td>no seu caso de teste Selenese, substituiremos seus espaços extras por apenas um espaço.

Esse problema tem uma solução alternativa simples. Definimos uma variável em Selenese ${space}, cujo valor é um espaço único. Você pode usar ${space}para inserir um espaço que não será cortado automaticamente, como este: <td>foo${space}${space}${space}</td>. Também incluímos uma variável ${nbsp}, que você pode usar para inserir um espaço sem quebra.

Observe que os XPaths não normalizam os espaços em branco da maneira que fazemos. Se você precisa escrever um XPath como //div[text()="hello world"], mas o HTML da ligação é realmente " hello&nbsp;world", você precisa inserir um real " &nbsp;" em seu caso de teste Selenese para obtê-lo para corresponder, como este: //div[text()="hello${nbsp}world"].


1
Ligação OpenQA não mais está a carregar com sucesso
kjosh

1
Eu só quero observar que $ {nbsp} não está funcionando para mim nas ferramentas de desenvolvimento do Selenium ou Chrome, nem o é \u00a0. O que funcionou para mim foi digitar um espaço sem interrupção, no mac Alt+Shift+Space. Pesquisa Alt+0160na Web diz no Windows.
Cynic

25

Descobri que posso fazer a correspondência quando insiro um espaço sem interrupção codificado (U + 00A0) digitando Alt + 0160 no Windows entre as duas aspas ...

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

trabalhou para mim com o char especial.

Pelo que entendi, o padrão XPath 1.0 não lida com caracteres de escape Unicode. Parece haver funções para isso no XPath 2.0, mas parece que o Firefox não o suporta (ou eu entendi algo errado). Então você tem a ver com a página de código local. Feio, eu sei.

Na verdade, parece que o padrão depende da linguagem de programação usando o XPath para fornecer a sequência de escape Unicode correta ... Então, de alguma forma, eu fiz a coisa certa.


Usando o Xpather 1.4.1 no Firefox 2, // td [text () = ''] não produz resultados.
Zack The Human

Desculpe. Isso não funciona para mim. Meu objetivo final é usá-lo no Selenium para os testes de minhas interfaces da Web. O próprio Selenium mantém as expressões de teste em uma estrutura XML e a digitação Alt Windows parece estar perdida no caminho. Além disso, o meu & # 160; retorna como um em XML.
21468 Bergeroy

Zack, como escrevi, você deve substituir o espaço entre as duas aspas pelo caractere produzido por Alt + 0160 (no teclado numérico).
PhiLho

4
Também tenho que trabalhar com o PHP com sucesso:$col = $xpath->query("//p[text()=\"\xC2\xA0\"]");
hakre

@Bergory isso funciona usando transferidor com selênio motorista
Damian Green


2

Tenha em mente que um processador XML compatível com os padrões terá substituído quaisquer outras de cinco ones padrão de XML referências de entidade ( &amp;, &gt;, &lt;, &apos;, &quot;) com o personagem correspondente na codificação alvo no momento em expressões XPath são avaliados. Dado esse comportamento, as sugestões de PhiLho e jsulak são o caminho a seguir, se você deseja trabalhar com ferramentas XML. Quando você insere &#160;a expressão XPath, ela deve ser convertida na sequência de bytes correspondente antes que a expressão XPath seja aplicada.


1
Não se você tentar / usar o XPath no XPather (GUI) ou no JavaScript (sem substituição automática de entidades, pois não estamos em XML). Bons conselhos em outros ambientes XML (XSTL?).
PhiLho

1

Não consigo obter uma correspondência usando o Xpather, mas o seguinte funcionou para mim com arquivos XML e XSL simples no XML Notepad da Microsoft:

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

O valor retornado é 1, que é o valor correto no meu caso de teste.

No entanto, tive que declarar o nbsp como uma entidade no meu XML e XSL usando o seguinte:

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

Eu não tenho certeza se isso ajuda você, mas eu era capaz de realmente encontrar nbsp usando uma expressão XPath.

Editar: Meu exemplo de código realmente contém os caracteres '& nbsp;' mas o destaque da sintaxe JavaScript o converte no caractere de espaço. Não se engane!


Você pode editar seu exemplo de código como foi feito para o exemplo na minha pergunta. Substitua sua entidade nbsp por & nbsp ;.
21468 Bergeroy

1

Procure &nbsp;ou apenas nbsp- você tentou isso?


Reconheço que isso deve funcionar, mas não é exatamente certo o que encontro. Deve haver uma maneira no XPATH de codificar uma certa maneira de corresponder ao que estou procurando.
Bergeroy 29/10/08

Talvez eu deva procurar uma expressão regular.
Bergeroy 29/10/08

1

De acordo com o HTML que você forneceu:

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

Para localizar o nó com a sequência, &nbsp;você pode usar um dos seguintes soluções baseadas em:

  • Usando text():

    "//td[text()='\u00A0']"
  • Usando contains():

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

No entanto, o ideal é evitar o caractere NO-BREAK SPACE e usar uma das seguintes estratégias de localização :

  • Usando o <tr>nó pai e following-sibling:

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

    "//tr//td[last()]"
  • Usando o <td>nó anterior e o followingnode andseguinte irmão:

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

Referência

Você pode encontrar uma discussão detalhada relevante em:


tl; dr

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


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.