Getting DOM elements by classname Getting DOM elements by classname php php

Getting DOM elements by classname


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();$dom->load($filePath);$finder = new DomXPath($dom);$classname="my-class";$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 the 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();$dom->load($filePath);$finder = new DomXPath($dom);$classname="my-class";$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 a lot 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\"]");


If you wish to get the innerhtml of the class without the zend you could use this:

$dom = new DomDocument();$dom->load($filePath);$classname = 'main-article';$finder = new DomXPath($dom);$nodes = $finder->query("//*[contains(concat(' ', normalize-space(@class), ' '), ' $classname ')]");$tmp_dom = new DOMDocument(); foreach ($nodes as $node)     {    $tmp_dom->appendChild($tmp_dom->importNode($node,true));    }$innerHTML.=trim($tmp_dom->saveHTML()); echo $innerHTML;


I think the accepted way is better, but I guess this might work as well

function getElementByClass(&$parentNode, $tagName, $className, $offset = 0) {    $response = false;    $childNodeList = $parentNode->getElementsByTagName($tagName);    $tagCount = 0;    for ($i = 0; $i < $childNodeList->length; $i++) {        $temp = $childNodeList->item($i);        if (stripos($temp->getAttribute('class'), $className) !== false) {            if ($tagCount == $offset) {                $response = $temp;                break;            }            $tagCount++;        }    }    return $response;}