babonk babonk - 3 months ago 17x
PHP Question

Getting DOM elements by classname

I'm using PHP DOM and I'm trying to get an element within a DOM node that have a given class name. What's the best way to get that sub-element?


Update: Xpath version of *[@class~='my-class'] css selector

So after my comment below in response to hakre's comment i got curious and looked into the code behind Zend_Dom_Query. It looks like the above selector is compiled to the following xpath (untested):

[contains(concat(' ', normalize-space(@class), ' '), ' my-class ')]

so the php would be:

$dom = new DomDocument();
$finder = new DomXPath($dom);
$nodes = $finder->query("//*[contains(concat(' ', normalize-space(@class), ' '), ' $classname ')]");

Basically all we do here is normalize the class attribute so that even a single class is bounded by spaces, and the complete class list is bounded in spaces. Then append class we are searching for with a space. This way we are effectively looking for and find only instances of my-class.

Use an xpath selector?

$dom = new DomDocument();
$finder = new DomXPath($dom);
$nodes = $finder->query("//*[contains(@class, '$classname')]");

If it is only ever one type of element you can replace the * with the particular tagname.

If you need to do alot of this with very complex selector i would recommend Zend_Dom_Query which supports CSS selector syntax (a la jQuery):

$finder = new Zend_Dom_Query($html);
$classname = 'my-class';
$nodes = $finder->query("*[class~=\"$classname\"]");