¿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>

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. :)


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')]

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 ().


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')]

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 ... 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"]



1

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


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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.