blackdad
blackdad

Reputation: 1391

Getting element length with php DOM

I'm stuck with this. I try to use php dom to parse some html code. How can I get to know how many children current element has witch I iterate through in for loop?

<?php
$str='
<table id="tableId">
<tr>
    <td>row1 cell1</td>
    <td>row1 cell2</td>
</tr>
<tr>
    <td>row2 cell1</td>
    <td>row2 cell2</td>
</tr>
</table>
';

$DOM = new DOMDocument;
$DOM->loadHTML($str);   // loading page contents
$table = $DOM->getElementById('tableId');   // getting the table that I need
$DOM->loadHTML($table);     

$tr = $DOM->getElementsByTagName('tr');     // getting rows

echo $tr->item(0)->nodeValue;   // outputs row1 cell1 row1 cell2 - exactly as I expect with both rows
echo "<br>";
echo $tr->item(1)->nodeValue;   // outputs row2 cell1 row2 cell2

// now I need to iterate through each row to build an array with cells that it has
for ($i = 0; $i < $tr->length; $i++)
{
echo $tr->item($i)->length;     // outputs no value. But how can I get it?
echo $i."<br />";
}
?>

Upvotes: 0

Views: 7649

Answers (1)

Wrikken
Wrikken

Reputation: 70540

This will give you all childnodes:

$tr->item($i)->childNodes->length;

... but: it will contain DOMText nodes with whitespace etc (so the count is 4). If you don't necessarily need the length, just want to iterate over all the nodes, you can do this:

foreach($tr->item($i)->childNodes as $node){
    if($node instanceof DOMElement){
        var_dump($node->ownerDocument->saveXML($node));
    }
}

If you need only a length of elements, you can do this:

$x = new DOMXPath($DOM);
var_dump($x->evaluate('count(*)',$tr->item($i)));

And you can do this:

foreach($x->query('*',$tr->item($i)) as $child){
    var_dump($child->nodeValue);
}

foreach-ing through the ->childNodes has my preference for simple 'array-building'. Keep in mind you van just foreach through DOMNodeList's as if they were arrays, saves a lot of hassle.

Building a simple array from a table:

$DOM = new DOMDocument;
$DOM->loadHTML($str);   // loading page contents
$table = $DOM->getElementById('tableId'); 
$result = array();
foreach($table->childNodes as $row){
   if(strtolower($row->tagName) != 'tr') continue;
   $rowdata = array();
   foreach($row->childNodes as $cell){
       if(strtolower($cell->tagName) != 'td') continue;
       $rowdata[] = $cell->textContent;
   }
   $result[] = $rowdata;
}
var_dump($result);

Upvotes: 2

Related Questions