Quiero seleccionar solo una clase llamada .date
Por alguna razón, no puedo hacer que esto funcione. Si alguien sabe qué está mal con mi código, se lo agradecería mucho.
@$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." ";
}
contains(@class, 'date')
Respuestas:
Quiero escribir la respuesta canónica a esta pregunta porque la respuesta anterior tiene un problema.
Nuestro problema
El selector de CSS :
.foo
seleccionará cualquier elemento que tenga la clase foo .
¿Cómo se hace esto en XPath?
Aunque XPath es más poderoso que CSS, XPath no tiene un equivalente nativo de un selector de clases CSS . Sin embargo, existe una solución.
La forma correcta de hacerlo
El selector equivalente en XPath es:
//*[contains(concat(" ", normalize-space(@class), " "), " foo ")]
La función normalizar el espacio 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) también es el equivalente del selector CSS:
*[class~="foo"]
que coincidirá con cualquier elemento cuyo valor de atributo de clase sea 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 espacios en blanco adicionales alrededor del nombre de la clase:
<div class=" foo ">
El selector XPath 'mejorado'
//*[contains(@class, "foo")]
¡tampoco funciona! porque coincide incorrectamente con elementos de la clase foobar , por ejemplo
<div class="foobar">
El crédito es para este tipo, que fue la primera solución publicada para este problema que encontré en la web: http://dubinko.info/blog/2007/10/01/simple-parsing-of-space-seprated-attributes- in-xpathxslt /
fuente
<div class="foo\tbar">
? Quiero decir, nombres de clases separados por una pestaña.//*[contains(concat(" ", normalize-space(@class), " "), " foo ")]
?//[@class="date"]
no es un xpath válido.Prueba
//*[@class="date"]
, o si sabes que es una imagen,//img[@class="date"]
fuente
XPath 3.1 introduce una función contiene-token y, por tanto, finalmente resuelve esto 'oficialmente'. Está diseñado para apoyar clases .
Ejemplo:
//*[contains-token(@class, "foo")]
Esta función asegura que el espacio en blanco (no solo
(U + 0020)) se maneja correctamente, funciona en caso de repetición del nombre de clase y generalmente cubre los casos extremos.
Nota: A partir de hoy (13/12/2016) XPath 3.1 tiene el estado de recomendación candidata .
fuente
En XPath 2.0 puede:
//*[count(index-of(tokenize(@class, '\s+' ), 'foo')) = 1]
como lo declaró Christian Weiske en: https://cweiske.de/tagebuch/XPath%3A%20Select%20element%20by%20class.htm
fuente
HTML permite nombres de atributos y elementos que no distinguen entre mayúsculas y minúsculas y luego la clase es una lista de nombres de clase separada por espacios. Aquí vamos por una
img
etiqueta y elclass
nombredate
://*['IMG' = translate(name(.), 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')]/@*['CLASS' = translate(name(.), 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') and contains(concat(' ', normalize-space(.), ' '), concat(' ', 'date', ' '))]
Ver también: Conversión de CSS Selector a XPath
fuente
¡¡¡CUIDADO CON LOS SIGNOS MENOS EN LA PLANTILLA !!! Si está consultando "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.
fuente