Seleccionar una clase css con xpath


Quiero seleccionar solo una clase llamada por sí misma .fecha

Por alguna razón, no puedo hacer que esto funcione. Si alguien sabe lo que está mal con mi código, sería muy apreciado.

@$doc = new DOMDocument();
@$doc->loadHTML($html);
$xml = simplexml_import_dom($doc); // just to make xpath more simple
$images = $xml->xpath('//[@class="date"]');                             
foreach ($images as $img)
{
    echo  $img." ";
}
Author: hakre, 2012-01-10

6 answers

Quiero escribir la respuesta canónica a esta pregunta porque la respuesta anterior tiene un problema.

Nuestro problema

El selector CSS :

.foo

Seleccionará cualquier elemento que tenga la clase foo.

¿Cómo se hace esto en XPath?

Aunque XPath es más potente que CSS, XPath no tiene un equivalente nativo de un selector de clase CSS. Sin embargo, hay una solución.

La manera correcta de hacer it

El selector equivalente en XPath es:

//*[contains(concat(" ", normalize-space(@class), " "), " foo ")]

La función normalize-space elimina los espacios en blanco iniciales y finales (y también reemplaza las secuencias de caracteres de espacios en blanco por un solo espacio).

(En un sentido más general) este es también el equivalente del selector CSS:

*[class~="foo"]

Que coincidirá con cualquier elemento cuyo valor de atributo class es una lista de valores separados por espacios en blanco, uno de los cuales es exactamente igual a foo .

Un par de formas obvias, pero incorrectas de hacerlo

El selector XPath:

//*[@class="foo"]

No funciona! porque no coincidirá con un elemento que tenga más de una clase, por ejemplo

<div class="foo bar">

Tampoco coincidirá si hay algún espacio en blanco adicional alrededor del nombre de la clase:

<div class="  foo ">

El selector XPath 'mejorado'

//*[contains(@class, "foo")]

¡Tampoco funciona! debido a que coincide erróneamente elementos con la clase foobar , para ejemplo

<div class="foobar">

El crédito va a este tipo, que fue la primera solución publicada a este problema que encontré en la web: http://dubinko.info/blog/2007/10/01/simple-parsing-of-space-seprated-attributes-in-xpathxslt/

 225
Author: user716736,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-17 09:49:54

//[@class="date"] no es un xpath válido.

Intenta //*[@class="date"], o si sabes que es una imagen, //img[@class="date"]

 9
Author: MrGlass,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-01-10 19:05:01

XPath 3.1 introduce una función contains-token y finalmente resuelve esto 'oficialmente'. Está diseñado para soportar clases.

Ejemplo:

//*[contains-token(@class, "foo")]

Esta función se asegura de que el espacio en blanco (no solo (U + 0020)) se maneja correctamente, funciona en caso de repetición de nombre de clase, y generalmente cubre los casos de borde.


Nota: A partir de hoy (2016-12-13) XPath 3.1 tiene el estatus de Candidato Recomendación.

 7
Author: Robin Pokorný,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-13 17:09:05

En XPath 2.0 puedes:

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

Como declaró Christian Weiske en: https://cweiske.de/tagebuch/XPath%3A%20Select%20element%20by%20class.htm

 3
Author: Memke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-09 13:33:07

HTML permite nombres de elementos y atributos que no distinguen entre mayúsculas y minúsculas y luego class es una lista de nombres de clases separados por espacios. Aquí vamos por una etiqueta img y el class llamado date:

//*['IMG' = translate(name(.), 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')]/@*['CLASS' = translate(name(.), 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') and contains(concat(' ', normalize-space(.), ' '), concat(' ', 'date', ' '))]

Véase también: Selector de CSS a conversión XPath

 1
Author: hakre,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-13 16:36:02

¡CUIDADO CON LOS SIGNOS NEGATIVOS EN LA PLANTILLA !!! Si está preguntando por "my-ownclass" en DOM:

<ul class="my-ownclass"><li>...</li></ul>
<ul class="someother"><li>...</li></ul>
<ul><li>...</li></ul>

$finder = new DomXPath($dom);
$nodes = $finder->query(".//ul[contains(@class, 'my-ownclass')]"); // This will NOT behave as expected! This will strangely match all the <ul> elements in DOM.
$nodes = $finder->query(".//ul[contains(@class, 'ownclass')]"); // This will match the element.
 1
Author: Vlado,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-30 07:43:28