Estoy usando PHP DOM y estoy tratando de obtener un elemento dentro de un nodo DOM que tenga un nombre de clase dado. ¿Cuál es la mejor manera de obtener ese subelemento?
Actualización: terminé usando Mechanize
PHP, que era mucho más fácil de trabajar.
Respuestas:
Actualización: versión Xpath del
*[@class~='my-class']
selector cssEntonces, después de mi comentario a continuación en respuesta al comentario de hakre, sentí curiosidad y busqué en el código detrás
Zend_Dom_Query
. Parece que el selector anterior está compilado en el siguiente xpath (no probado):[contains(concat(' ', normalize-space(@class), ' '), ' my-class ')]
entonces el php sería:
Básicamente, todo lo que hacemos aquí es normalizar el
class
atributo para que incluso una sola clase esté limitada por espacios, y la lista de clases completa esté limitada por espacios. Luego agregue la clase que estamos buscando con un espacio. De esta manera, estamos buscando y encontrando de manera efectiva instancias demy-class
.¿Usar un selector xpath?
Si solo es un tipo de elemento, puede reemplazarlo
*
con el nombre de etiqueta particular.Si necesita hacer mucho de esto con un selector muy complejo, recomendaría
Zend_Dom_Query
que admita la sintaxis del selector CSS (a la jQuery):fuente
my-class2
también, pero muy dulce. ¿Alguna forma de elegir solo el primero de todos los elementos?class
puede tener más de una clase, por ejemplo:<a class="my-link link-button nav-item">
.//*[contains(concat(' ', normalize-space(@class), ' '), ' classname ')]
(Muy informativo: Selectores CSS y Expresiones XPath ).contains
en combinación conconcat
... solo estamos discutiendo los detalles de rellenar los espacios en ambos lados de la clase que está buscando o solo rellenar un lado. Sin embargo, cualquiera debería funcionar.Si desea obtener el innerhtml de la clase sin el zend, puede usar esto:
fuente
$classname = 'main-article'
Creo que la forma aceptada es mejor, pero supongo que esto también podría funcionar.
fuente
$classResult = getElementByClass($dom, 'div', 'm-signature-pad'); $classResult->nodeValue = ''; $enode = $dom->createElement('img'); $enode->setAttribute('src', $signatureImage); $classResult->appendChild($enode);
También hay otro enfoque sin el uso de
DomXPath
oZend_Dom_Query
.Basado en la función original de dav, escribí la siguiente función que devuelve todos los hijos del nodo padre cuya etiqueta y clase coinciden con los parámetros.
supongamos que tiene una variable
$html
el siguiente HTML:El uso de
getElementsByClass
es tan simple como:fuente
DOMDocument es lento de escribir y phpQuery tiene problemas de pérdida de memoria. Terminé usando:
https://github.com/wasinger/htmlpagedom
Para seleccionar una clase:
Espero que esto ayude a alguien más también
fuente