Uso de XPATH para buscar texto que contenga & nbsp;

120

Utilizo XPather Browser para comprobar mis expresiones XPATH en una página HTML.

Mi objetivo final es usar estas expresiones en Selenium para probar mis interfaces de usuario.

Obtuve un archivo HTML con un contenido similar a este:

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

Quiero seleccionar un nodo con un texto que contenga la cadena " &nbsp;".

Con una cadena normal como "abc" no hay problema. Yo uso un XPATH similar a //td[text()="abc"].

Cuando intento con un XPATH como, //td[text()="&nbsp;"]no devuelve nada. ¿Existe una regla especial para los textos con " &"?

Bergeroy
fuente
¿Su transformación XSL real no devuelve nada? ¿O solo Xpather?
Zack The Human

Respuestas:

89

Parece que OpenQA , los chicos detrás de Selenium, ya han abordado este problema. Definieron algunas variables para hacer coincidir explícitamente los espacios en blanco. En mi caso, necesito usar un XPATH similar a//td[text()="${nbsp}"] .

Reproduje aquí el texto de OpenQA sobre este tema (que se encuentra aquí ):

HTML normaliza automáticamente los espacios en blanco dentro de los elementos, ignorando los espacios iniciales / finales y convirtiendo espacios adicionales, pestañas y nuevas líneas en un solo espacio. Cuando Selenium lee el texto de la página, intenta duplicar este comportamiento, por lo que puede ignorar todas las pestañas y nuevas líneas en su HTML y hacer afirmaciones basadas en cómo se ve el texto en el navegador cuando se procesa. Hacemos esto reemplazando todos los espacios en blanco no visibles (incluido el espacio no divisible " &nbsp;") con un solo espacio. Todas las nuevas líneas visibles ( <br>, <p>y las <pre>nuevas líneas formateadas) deben conservarse.

Usamos la misma lógica de normalización en el texto de las tablas de casos de prueba de HTML Selenese. Esto tiene varias ventajas. Primero, no es necesario mirar el código fuente HTML de la página para averiguar cuáles deberían ser sus afirmaciones; Los &nbsp;símbolos " " son invisibles para el usuario final, por lo que no debería tener que preocuparse por ellos al escribir pruebas de Selenese. (No es necesario que coloque &nbsp;marcadores " " en su caso de prueba para afirmarTexto en un campo que contenga " &nbsp;".) También puede colocar nuevas líneas y espacios adicionales en sus <td>etiquetas selenesas ; dado que usamos la misma lógica de normalización en el caso de prueba que en el texto, podemos asegurarnos de que las afirmaciones y el texto extraído coincidan exactamente.

Esto crea un pequeño problema en esas raras ocasiones en las que realmente desea / necesita insertar espacios en blanco adicionales en su caso de prueba. Por ejemplo, es posible que deba escribir texto en un campo como este: " foo ". Pero si simplemente escribes<td>foo </td> en su caso de prueba de Selenese, reemplazaremos sus espacios adicionales con un solo espacio.

Este problema tiene una solución sencilla. Hemos definido una variable en selenese ${space}, cuyo valor es un solo espacio. Se puede utilizar ${space}para insertar un espacio que no es necesario cortar de forma automática, así: <td>foo${space}${space}${space}</td>. También hemos incluido una variable ${nbsp} que puede utilizar para insertar un espacio que no se rompa.

Tenga en cuenta que los XPaths no normalizan los espacios en blanco como lo hacemos nosotros. Si tiene que escribir un XPath como //div[text()="hello world"], pero el código HTML del enlace es realmente " hello&nbsp;world", tendrá que insertar un verdadero " &nbsp;" en el caso de test Selenese para conseguir que coincide, como esto: //div[text()="hello${nbsp}world"].

Bergeroy
fuente
1
El enlace de OpenQA ya no se carga con éxito
kjosh
1
Solo quiero señalar que $ {nbsp} no me funciona en las herramientas de desarrollo de Selenium o Chrome, tampoco \u00a0. Lo que funcionó para mí fue escribir un espacio sin interrupciones, en mac Alt+Shift+Space. La búsqueda web dice Alt+0160en Windows.
Cynic
25

Descubrí que puedo hacer la coincidencia cuando ingreso un espacio sin ruptura codificado (U + 00A0) escribiendo Alt + 0160 en Windows entre las dos comillas ...

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

funcionó para mí con el char especial.

Por lo que entendí, el estándar XPath 1.0 no maneja el escape de caracteres Unicode. Parece que hay funciones para eso en XPath 2.0, pero parece que Firefox no lo admite (o no entendí algo). Entonces tienes que ver con la página de códigos local. Feo, lo sé.

En realidad, parece que el estándar se basa en el lenguaje de programación que usa XPath para proporcionar la secuencia de escape Unicode correcta ... Entonces, de alguna manera, hice lo correcto.

PhiLho
fuente
Usando Xpather 1.4.1 en Firefox 2, // td [text () = ''] no arroja resultados.
Zack The Human
Lo siento. No me funciona. Mi objetivo final es usarlo en Selenium para las pruebas de mis interfaces web. El propio selenio mantiene las expresiones de prueba en una estructura XML y la escritura de Alt Windows parece perderse en el camino. Además, mi & # 160; devuelve como en XML.
Bergeroy
Zack, como escribí, debes reemplazar el espacio entre las dos comillas por el carácter producido por Alt + 0160 (en el teclado numérico).
PhiLho
4
También $col = $xpath->query("//p[text()=\"\xC2\xA0\"]");
pude
@Bergory Esto funciona usando Transportador con controlador Selenium
Damian Green
2

Tenga en cuenta que un procesador XML compatible con los estándares se han sustituido las referencias a entidades distintas de las estándar de cinco XML ( &amp;, &gt;, &lt;, &apos;, &quot;) con el carácter correspondiente en la codificación de destino en el momento se evalúan las expresiones XPath. Dado ese comportamiento, las sugerencias de PhiLho y jsulak son el camino a seguir si desea trabajar con herramientas XML. Cuando ingresa &#160;la expresión XPath, debe convertirse a la secuencia de bytes correspondiente antes de aplicar la expresión XPath.

ChuckB
fuente
1
No si prueba / usa XPath en XPather (GUI) o en JavaScript (sin sustitución automática de entidades, ya que no estamos en XML). Buen consejo en otros entornos XML (¿XSTL?).
PhiLho
1

No puedo obtener una coincidencia usando Xpather, pero lo siguiente funcionó para mí con archivos XML y XSL simples en el Bloc de notas XML de Microsoft:

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

El valor devuelto es 1, que es el valor correcto en mi caso de prueba.

Sin embargo, tuve que declarar nbsp como una entidad dentro de mi XML y XSL usando lo siguiente:

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

No estoy seguro de si eso le ayuda, pero yo era capaz de realmente encontrar nbsp utilizando una expresión XPath.

Editar: mi ejemplo de código contiene los caracteres "& nbsp;" pero el resaltado de sintaxis de JavaScript lo convierte al carácter de espacio. ¡No se deje engañar!

Zack el humano
fuente
Puede editar su muestra de código como se hizo para la muestra en mi pregunta. Reemplace su entidad nbsp por & amp; nbsp ;.
Bergeroy
1

Buscar &nbsp;o solo nbsp: ¿intentaste esto?

Nakilon
fuente
Reconozco que esto debería funcionar, pero no estoy exactamente seguro de lo que encuentro. Debe haber una forma en XPATH de codificar de cierta forma que coincida con lo que estoy buscando.
Bergeroy
Quizás debería mirar hacia una expresión regular.
Bergeroy
1

Según el HTML que ha proporcionado:

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

Para localizar el nodo con la cadena &nbsp; , puede usar cualquiera de los siguientes soluciones basadas:

  • Usando text():

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

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

Sin embargo, lo ideal sería evitar el carácter de ESPACIO SIN ROTURA y utilizar cualquiera de las siguientes Estrategias de localización :

  • Usando el <tr>nodo padre y following-sibling:

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

    "//tr//td[last()]"
  • Usando el <td>nodo anterior y el followingnode andsiguiente hermano`:

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

Referencia

Puede encontrar una discusión detallada relevante en:


tl; Dr

Carácter Unicode 'ESPACIO SIN INTERRUPCIÓN' (U + 00A0)

DebanjanB
fuente