node - xpath php
¿Cómo puedo hacer coincidir un atributo que contiene una cadena determinada? (9)
Tengo problemas para seleccionar nodos por atributo cuando los atributos contienen más de una palabra. Por ejemplo:
<div class="atag btag" />
Esta es mi expresión xpath:
//*[@class=''atag'']
La expresión trabaja con
<div class="atag" />
pero no para el ejemplo anterior. ¿Cómo puedo seleccionar el <div>
?
Esto los seleccionará a todos sin importar 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 el 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. Este es casi siempre el caso. Si no es así, debes hacerlo aún más difícil de manejar:
//*[contains(concat('' '', normalize-space(@class), '' ''), '' atag '')]
(La selección de cadenas separadas por espacios similares a los nombres de clase es un caso tan común que sorprende que no tenga una función XPath específica para él, como ''[class ~ = "atag"] de CSS3.)
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 en el que tiene una coincidencia en la cadena.
Para los enlaces que contiene url común hay que consolar en una variable. Entonces inténtalo 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; <linkCount;i++)
{
driver.findelement(allLinks[i]).click();
}
Puedes probar lo siguiente
By.CssSelector("div.atag.btag")
Tenga en cuenta que la respuesta de Bobince podría ser demasiado complicada si puede asumir que el nombre de la clase que le interesa no es una subcadena de otro nombre de clase posible . Si esto es cierto, simplemente puede utilizar la concordancia de subcadenas a través de la función de contenido. 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 elementos que no pretende. En este caso, tienes que encontrar los límites de la palabra. Al usar los delimitadores de espacio 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 matag
.
Una 2.0 XPath que funciona:
//*[tokenize(@class,''/s+'')=''atag'']
o con una variable:
//*[tokenize(@class,''/s+'')=$classname]
intente esto: //*[contains(@class, ''atag'')]
EDITAR : vea la solución de bobince, que utiliza contiene en lugar de comenzar , junto con un truco para garantizar que la comparación se realice al nivel de un token completo (para que no se encuentre el patrón ''atag'' como parte de otra ''etiqueta'').
"atag btag" es un valor impar para el atributo de clase, pero nunca menos, intente:
//*[starts-with(@class,"atag")]