PHP:简单的HTML Dom解析器 - 使用标题/不均匀的主体行解析HTML表

时间:2017-10-11 19:33:26

标签: php html parsing simple-html-dom

我有一个格式如下的HTML表格:如您所见,第一个标题1有一个与之关联的第1行。第二个标题2有两行 - 第2行,第3行与之关联。标题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 Simple HTML Dom解析器来获取以下数据:

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

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

2 个答案:

答案 0 :(得分:1)

您可以使用标准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']
]

答案 1 :(得分:1)

如果没有看到您现有的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以用于其他原因。