PHP:简单 HTML Dom 解析器 - 解析 HTML table 和 headers/uneven body 行

PHP: Simple HTML Dom parser - Parse HTML table with headers/uneven body rows

我有一个 HTML table,格式如下: 如您所见,第一个 Header 1 有一个与之关联的第 1 行。第二个 Header 2 有两行 - 第 2 行,第 3 行与其关联。 Header 3 有第 4 行、第 5 行、第 6 行与之关联。

<table>
<thead>
    <tr>
        <th>Header 1</th>
    </tr>
</thead>
<tbody>
        <tr>
            <td>
                Row 1
            </td>
        </tr>
</tbody>
<thead>
    <tr>
        <th>Header 2</th>
    </tr>
</thead>
<tbody>
        <tr>
            <td>
                Row 2
            </td>
        </tr>
        <tr>
            <td>
                Row 3
            </td>
        </tr>

</tbody>
<thead>
    <tr>
        <th>Header 3</th>
    </tr>
</thead>
<tbody>
        <tr>
            <td>
                Row 4
            </td>
        </tr>
        <tr>
            <td>
                Row 5
            </td>
        </tr>
        <tr>
            <td>
                Row 6
            </td>
        </tr>
</tbody>

我想使用 PHP 简单 HTML Dom 解析器来获取以下数据:

Header 1, Row 1
Header 2, Row 2, Row 3
Header 3, Row 4, Row 5, Row 6

当我使用解析器获取标签时,所有标签都存储在一个数组中。当我执行 foreach 循环时,所有其他标签都存储在另一个数组中。如何在循环时保留 headers 与行的关联?

您可以使用标准 DOMDocument 界面来执行此操作。如果您的 HTML 存储在变量 $html 中,则执行:

$dom = new DOMDocument();
$dom->loadHTML($html);
foreach ($dom->getElementsByTagName('tr') as $row) {
    if ($row->parentNode->tagName === 'thead') $arr[] = [];
    $arr[count($arr)-1][] = trim($row->textContent);
}

在运行上面之后,变量$arr会有这样的内容:

[
    ['Header 1', 'Row 1'],
    ['Header 2', 'Row 2', 'Row 3'],
    ['Header 3', 'Row 4', 'Row 5', 'Row 6']
]

如果没有看到您现有的 php 代码,很难确切地说出如何更改您拥有的代码。但是这样的事情适用于您的用例:

//Assuming $html has been set to your html block
$heads = $html->find('thead');
$result = array();

foreach($heads as $head){
    $headerText = $head->find('th')[0]->innerText;
    $result[$headerText] = array();
    $rows = $head->next_sibling()->find('td');
    foreach($rows as $row){
        $result[$headerText][] = $row->innerText;
    }
}

//Output
foreach($result as $header => $rows){
    echo $header . ': ' . implode(',', $rows);
}

一些注意事项,以上是您想要执行的操作的简单示例。这是一个相当天真的实现。例如。它假设给定的 thead 只会恰好有 1 th.

此外,如果你真的只想回显它,直接在解析循环中回显会更有效。我将输出分开,因为我假设您想要做的不仅仅是将其打印到屏幕上。

请注意,使用本机 dom 解析器执行此类操作相当简单,我假设您出于某些其他原因需要使用简单的 html dom。