¿Cómo puedo unirme a un atributo que contiene una cierta cadena?

Tengo problemas para seleccionar nodos por atributo cuando los atributos contienen más de una palabra. Por ejemplo:

Esta es mi expresión xpath:

//*[@class='atag']

La expresión funciona con

pero no para el ejemplo anterior. ¿Cómo puedo seleccionar el

?

Esto los seleccionará a todos independientemente de la posición de los atributos

 //div[contains(@class, 'atag') and contains(@class ,'btag')] 

La respuesta de mjv es un buen comienzo pero fallará si atag no es el primer nombre de clase en la lista.

El enfoque habitual es bastante difícil de manejar:

 //*[contains(concat(' ', @class, ' '), ' atag ')] 

esto funciona siempre que las clases estén separadas solo por espacios y no por otras formas de espacios en blanco. Esto es casi siempre el caso. Si no es así, tienes que hacerlo aún más difícil de manejar:

 //*[contains(concat(' ', normalize-space(@class), ' '), ' atag ')] 

(La selección por cadenas separadas por espacios similares a nombres de clases es un caso tan común que es sorprendente que no haya una función XPath específica para ello, como ‘[class ~ = “atag”]’ de CSS3).

EDITAR : vea la solución de bobince que usa contiene en lugar de comenzar con , junto con un truco para asegurarse de que la comparación se realiza al nivel de un token completo (no sea que el patrón ‘atag’ se encuentre como parte de otra ‘etiqueta’).

“atag btag” es un valor impar para el atributo de clase, pero sin embargo, intente:

 //*[starts-with(@class,"atag")] 

Un XPath 2.0 que funciona:

 //*[tokenize(@class,'\s+')='atag'] 

o con una variable:

 //*[tokenize(@class,'\s+')=$classname] 

Tenga en cuenta que la respuesta de Bobince puede ser demasiado complicada si puede asumir que el nombre de clase que le interesa no es una subcadena de otro posible nombre de clase . Si esto es cierto, simplemente puede usar la coincidencia de subcadenas mediante la función contains. Lo siguiente coincidirá con cualquier elemento cuya clase contenga la subcadena ‘atag’:

 //*[contains(@class,'atag')] 

Si la suposición anterior no se cumple, una coincidencia de subcadena coincidirá con los elementos que no pretende. En este caso, debe encontrar los límites de la palabra. Al usar los delimitadores espaciales para encontrar los límites del nombre de la clase, la segunda respuesta de bobince encuentra las coincidencias exactas:

 //*[contains(concat(' ', normalize-space(@class), ' '), ' atag ')] 

Esto coincidirá con atag y no con matag .

intente esto: //[contains(@class, 'atag')]

Para agregar a la respuesta de Bobince … Si la herramienta / biblioteca que usa usa Xpath 2.0, también puede hacer esto:

 //*[count(index-of(tokenize(@class, '\s+' ), $classname)) = 1] 

count () es aparentemente necesario porque index-of () devuelve una secuencia de cada índice con el que coincide en la cadena.

Puedes probar lo siguiente

By.CssSelector("div.atag.btag")

Para los enlaces que contienen url común tienen que consolar en una variable. Luego intente secuencialmente.

 webelements allLinks=driver.findelements(By.xpath("//a[contains(@href,'http://122.11.38.214/dl/appdl/application/apk')]")); int linkCount=allLinks.length(); for(int i=0;