-2

I am trying to parse the cell values of an HTML table to an indexed array of associative arrays with predetermined keys using PHP.

$htmlContent = '<table>
  <tr>
    <th>test1</th>
    <td>test1-1</td>
  </tr>
  <tr>
    <th>test2</th>
    <td>test2-2</td>
  </tr>
</table>';

I'd like this result:

[
    ['name' => "test1", 'value' => "test1-1"],
    ['name' => "test2", 'value' => "test2-2"],
]

My current result is only:

[
    ['test1' => 'test1-1', 'test2' => 'test2-2']
];

Here my coding attempt:

$DOM = new DOMDocument();
$DOM->loadHTML($htmlContent);

$Header = $DOM->getElementsByTagName('th');
$Detail = $DOM->getElementsByTagName('td');

//#Get header name of the table
foreach($Header as $NodeHeader) 
{
    $aDataTableHeaderHTML[] = trim($NodeHeader->textContent);
}
//print_r($aDataTableHeaderHTML); die();

//#Get row data/detail table without header name as key
$i = 0;
$j = 0;
foreach($Detail as $sNodeDetail) 
{
    $aDataTableDetailHTML[$j][] = trim($sNodeDetail->textContent);
    $i = $i + 1;
    $j = $i % count($aDataTableHeaderHTML) == 0 ? $j + 1 : $j;
}
//print_r($aDataTableDetailHTML); die();

//#Get row data/detail table with header name as key and outer array index as row number
for($i = 0; $i < count($aDataTableDetailHTML); $i++)
{
    for($j = 0; $j < count($aDataTableHeaderHTML); $j++)
    {
        $aTempData[$i][$aDataTableHeaderHTML[$j]] = $aDataTableDetailHTML[$i][$j];
    }
}
$aDataTableDetailHTML = $aTempData;
unset($aTempData);
print_r($aDataTableDetailHTML);
die();
11
  • Yes it's possible, you'll need to iterate through the table rows and cells and organize the data into an array with the 'name' and 'value' keys. Commented Nov 6, 2023 at 19:56
  • thank you. can you please give me an example code Commented Nov 6, 2023 at 21:47
  • What have you tried so far? Since there is no example code for this instead it would directly result in an answer Commented Nov 6, 2023 at 21:50
  • I Cant add the code here. I don't know the reason but here is the code codeproject.com/Tips/1074174/… Commented Nov 6, 2023 at 21:56
  • Okay so that's one solution you already have and referring to, what's the issue you are facing? Commented Nov 6, 2023 at 22:02

2 Answers 2

0

Your code is working too hard to try to keep the columnar data with the respective row.

To make things easier, iterate the row (<tr>) elements, then access the elements within the given row.

Code (Demo) or (Alternative Demo)

$dom = new DOMDocument();
$dom->loadHTML($html);
$result = [];
foreach ($dom->getElementsByTagName('tr') as $row) {
    $result[] = [
        'name' => $row->getElementsByTagName('th')->item(0)->nodeValue,
        'value' => $row->getElementsByTagName('td')->item(0)->nodeValue,
    ];
}
var_export($result);
Sign up to request clarification or add additional context in comments.

Comments

-1

I'll do this just because it was fun using explode and str_replace -- doing it without a PHP DOM parser ..

Basically create a starting Main empty array using explode( '</tr>', $table );, and loop through it, add the temp arrays to it after stripping unwanted content (IE <tr> and trimming)

<?php

$table = <<<HTML
<table>
  <tr>
    <th>Name</th>
    <th>Value</th>
  </tr>
  <tr>
    <td>Name One</td>
    <td>Value One</td>
  </tr><tr>
    <td>Name Two</td>
    <td>Value Two</td>
  </tr><tr>
    <td>Name Three</td>
    <td>Value Three</td>
  </tr>
</table>
HTML;

$rows = explode( '</tr>', $table );
array_shift($rows);
array_pop($rows);

$main_arr = [];

foreach ($rows as $row){
  $name = trim( str_replace(['<td>', '<tr>'], '', explode('</td>', $row)[0] ) );
  $value = trim( str_replace(['<td>', '<tr>'], '', explode('</td>', $row)[1] ) );

  $tmp_arr = [];
  $tmp_arr['name'] = $name;
  $tmp_arr['value'] = $value;

  $main_arr[] = $tmp_arr;

}

print_r($main_arr);

Your output should be:

Array
(
    [0] => Array
        (
            [name] => Name One
            [value] => Value One
        )

    [1] => Array
        (
            [name] => Name Two
            [value] => Value Two
        )

    [2] => Array
        (
            [name] => Name Three
            [value] => Value Three
        )

)

UPDATE

Here is the PHP DOM code that does the same thing:

<?php

$DOM = new DOMDocument();
$DOM->loadHTML("<table>
  <tr>
    <th>Name</th>
    <th>Value</th>
  </tr>
  <tr>
    <td>Name One</td>
    <td>Value One</td>
  </tr><tr>
    <td>Name Two</td>
    <td>Value Two</td>
  </tr><tr>
    <td>Name Three</td>
    <td>Value Three</td>
  </tr>
</table>");
$main_arr = [];
$rows = $DOM->getElementsByTagName("tr");
for ($i = 0; $i < $rows->length; $i++) {
    $cols = $rows->item($i)->getElementsbyTagName("td");
    $tmp_arr = [];
    if ($cols->item(0)->nodeValue){
      $tmp_arr['name'] = $cols->item(0)->nodeValue;
      $tmp_arr['value'] = $cols->item(1)->nodeValue;
      $main_arr[] = $tmp_arr;
    }
}

print_r( $main_arr );

5 Comments

thank you sir. can I do it using PHP DOM?
I added the PHP DOM way of doing it .. You should edit your question to specify :)
can you please help me to get it work for this table <tr><th class="col label" scope="row">test1</th><td ">test1-1</td></tr>
i think we need to do $Header = $DOM->getElementsByTagName('th'); but how to add it to your code
@Zak: regarding a recent comment of yours on a different answer, yes, it was an AI generated answer, one where the spam-link was added days later in an edit.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.