¿Cuál es la XPath correcta para elegir atributos que contienen "foo"?

176

Dado este XML, lo que XPath devuelve todos los elementos cuyo propatributo contiene Foo(los primeros tres nodos):

<bla>
 <a prop="Foo1"/>
 <a prop="Foo2"/>
 <a prop="3Foo"/>
 <a prop="Bar"/>
</bla>
ripper234
fuente
1
¿Por qué todos miran el atributo "prop"? ¿Me he perdido algo? Solo dice obtener los primeros tres nodos.
66
Todos miran el atributo prop porque eso fue lo que se les pidió. Obtenga todos los nodos donde el accesorio contiene "Foo". Agregue <a prop="Foo5" /> y verá por qué no se trata solo de "los primeros tres nodos" ..
erlando
La pregunta en el cuerpo está mal redactada, independientemente del título. ¿Puede realmente estar en cualquier atributo de apoyo, o realmente solo quieres los primeros tres nodos?
3
Sí, consulte el título por favor (y siéntase libre de editar).
ripper234
Si necesita una comparación entre mayúsculas y minúsculas, vea find-an-element-cuyo-atributo-contiene-un-texto-mayúsculas y minúsculas
Michael Freidgeim

Respuestas:

307
//a[contains(@prop,'Foo')]

Funciona si uso este XML para obtener resultados.

<bla>
 <a prop="Foo1">a</a>
 <a prop="Foo2">b</a>
 <a prop="3Foo">c</a>
 <a prop="Bar">a</a>
</bla>

Editar: Otra cosa a tener en cuenta es que, si bien el XPath anterior devolverá la respuesta correcta para ese xml en particular, si desea garantizar que solo obtenga los elementos "a" en el elemento "bla", como otros han mencionado, también debe usar

/bla/a[contains(@prop,'Foo')]

Esto buscará todos los elementos "a" en todo su documento xml, independientemente de estar anidado en un elemento "bla"

//a[contains(@prop,'Foo')]  

Agregué esto en aras de la minuciosidad y en el espíritu de stackoverflow. :)

evilhomer
fuente
3
xmlme.comahora redirige a otro host y no parece alojar la herramienta ni nada parecido.
jpmc26
26

Este XPath le dará todos los nodos que tienen atributos que contienen 'Foo', independientemente del nombre del nodo o el nombre del atributo:

//attribute::*[contains(., 'Foo')]/..

Por supuesto, si está más interesado en el contenido del atributo, y no necesariamente en su nodo principal, simplemente suelte el / ..

//attribute::*[contains(., 'Foo')]
Alex Beynenson
fuente
2
Para todos los nodos//@*[contains(., 'Foo')]
aliopi
16
descendant-or-self::*[contains(@prop,'Foo')]

O:

/bla/a[contains(@prop,'Foo')]

O:

/bla/a[position() <= 3]

Disecado:

descendant-or-self::

El eje: busca a través de cada nodo debajo y el nodo en sí. A menudo es mejor decir esto que //. He encontrado algunas implementaciones donde // significa en cualquier lugar (descendiente o propio del nodo raíz). El otro usa el eje por defecto.

* or /bla/a

La etiqueta: una coincidencia de comodines, y / bla / a es una ruta absoluta.

[contains(@prop,'Foo')] or [position() <= 3]

La condición dentro de []. @prop es la abreviatura de attribute :: prop, ya que el atributo es otro eje de búsqueda. Alternativamente, puede seleccionar los primeros 3 utilizando la función position ().

1729
fuente
6

John C es el más cercano, pero XPath distingue entre mayúsculas y minúsculas, por lo que la XPath correcta sería:

/bla/a[contains(@prop, 'Foo')]
Metro Pitufo
fuente
4

¿Has probado algo como:

// a [contiene (@prop, "Foo")]

Nunca he usado la función contiene antes, pero sospecho que debería funcionar como se anuncia ...

toddk
fuente
@toddk ... has apuntado a un atributo no existente: @foo. Te gustaría apuntar a @prop ;-)
Pitufo de Metro el
4

Si también necesita hacer coincidir el contenido del enlace en sí, use text ():

//a[contains(@href,"/some_link")][text()="Click here"]

SomeDudeSomewhere
fuente
2

/ bla / a [contiene (@prop, "foo")]

David Hill
fuente
1

Para el código anterior ... // * [contiene (@ prop, 'foo')]

digiguru
fuente
esto es para cualquier elemento con foo in, pero el atributo debe ser "prop"
digiguru
1

prueba esto:

// a [contiene (@ prop, 'foo')]

eso debería funcionar para cualquier etiqueta "a" en el documento

Dani Duran
fuente