[php] 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: I ended up using Mechanize for PHP which was much easier to work with.

This question is related to php css dom

The answer is


DOMDocument is slow to type and phpQuery has bad memory leak issues. I ended up using:

https://github.com/wasinger/htmlpagedom

To select a class:

include 'includes/simple_html_dom.php';

$doc = str_get_html($html);
$href = $doc->find('.lastPage')[0]->href;

I hope this helps someone else as well


There is also another approach without the use of DomXPath or Zend_Dom_Query.

Based on dav's original function, I wrote the following function that returns all the children of the parent node whose tag and class match the parameters.

function getElementsByClass(&$parentNode, $tagName, $className) {
    $nodes=array();

    $childNodeList = $parentNode->getElementsByTagName($tagName);
    for ($i = 0; $i < $childNodeList->length; $i++) {
        $temp = $childNodeList->item($i);
        if (stripos($temp->getAttribute('class'), $className) !== false) {
            $nodes[]=$temp;
        }
    }

    return $nodes;
}

suppose you have a variable $html the following HTML:

<html>
 <body>
  <div id="content_node">
    <p class="a">I am in the content node.</p>
    <p class="a">I am in the content node.</p>
    <p class="a">I am in the content node.</p>    
  </div>
  <div id="footer_node">
    <p class="a">I am in the footer node.</p>
  </div>
 </body>
</html>

use of getElementsByClass is as simple as:

$dom = new DOMDocument('1.0', 'utf-8');
$dom->loadHTML($html);
$content_node=$dom->getElementById("content_node");

$div_a_class_nodes=getElementsByClass($content_node, 'div', 'a');//will contain the three nodes under "content_node".

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;
}

I prefer using Symfony for this. Their libraries are pretty nice.

Use the The DomCrawler Component

Example:

$browser = new HttpBrowser(HttpClient::create());
$crawler = $browser->request('GET', 'example.com');
$class = $crawler->filter('.class')->first();

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;

Examples related to php

I am receiving warning in Facebook Application using PHP SDK Pass PDO prepared statement to variables Parse error: syntax error, unexpected [ Preg_match backtrack error Removing "http://" from a string How do I hide the PHP explode delimiter from submitted form results? Problems with installation of Google App Engine SDK for php in OS X Laravel 4 with Sentry 2 add user to a group on Registration php & mysql query not echoing in html with tags? How do I show a message in the foreach loop?

Examples related to css

need to add a class to an element Using Lato fonts in my css (@font-face) Please help me convert this script to a simple image slider Why there is this "clear" class before footer? How to set width of mat-table column in angular? Center content vertically on Vuetify bootstrap 4 file input doesn't show the file name Bootstrap 4: responsive sidebar menu to top navbar Stylesheet not loaded because of MIME-type Force flex item to span full row width

Examples related to dom

How do you set the document title in React? How to find if element with specific id exists or not Cannot read property 'style' of undefined -- Uncaught Type Error adding text to an existing text element in javascript via DOM Violation Long running JavaScript task took xx ms How to get `DOM Element` in Angular 2? Angular2, what is the correct way to disable an anchor element? React.js: How to append a component on click? Detect click outside React component DOM element to corresponding vue.js component