提问人:Sergey B. 提问时间:11/7/2018 最后编辑:mickmackusaSergey B. 更新时间:11/8/2023 访问量:3354
将 HTML 表格数据转换为转置的二维数组
Convert HTML table data into transposed 2d array
问:
我需要从 HTML 表格中抓取数据,并将列式数据定向为 2d 数组的行。
我的代码没有显示正确的结构。
HTML 表格:
<html>
<head>
</head>
<body>
<table>
<tbody>
<tr>
<td>header</td>
<td>header</td>
<td>header</td>
</tr>
<tr>
<td>content</td>
<td>content</td>
<td>content</td>
</tr>
<tr>
<td>test</td>
<td>test</td>
<td>test</td>
</tr>
</tbody>
</table>
</body>
</html>
PHP代码:
$DOM = new \DOMDocument();
$DOM->loadHTML($valdat["table"]);
$Header = $DOM->getElementsByTagName('tr')->item(0)->getElementsByTagName('td');
$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($j = 0; $j < count($aDataTableHeaderHTML); $j++)
{
for($i = 1; $i < count($aDataTableDetailHTML); $i++)
{
$aTempData[][$aDataTableHeaderHTML[$j]][] = $aDataTableDetailHTML[$i][$j];
}
}
$aDataTableDetailHTML = $aTempData;
echo json_encode($aDataTableDetailHTML);
我的结果:
[{"header":["content"]},{"header":["test"]},{"header":["content"]},{"header":["test"]},{"header":["content"]},{"header":["test"]}]
我们需要这样的结果:
[
["header","content","test"],
["header","content","test"],
["header","content","test"]
]
答:
1赞
Harvey Fletcher
11/7/2018
#1
我添加了一些额外的代码,它会将数组分块为两个值,然后添加键,在本例中为“header”$aDataTableDetailHTML
//There are two elements that are not "header"
$aDataTableDetailHTML = array_chunk($aTempData, 2);
//For every item in the array
foreach($aDataTableDetailHTML as $key=>$tag){
//Dynamically get the name, in this case, "header"
$tagName = array_keys( $tag[0] )[0];
//Start an array containing the tagname ("header")
$tagOut = array( $tagName );
//Add the two values onto the array
$tagOut[] = $tag[0][$tagName][0];
$tagOut[] = $tag[1][$tagName][0];
//Drop the keys from the array
$aDataTableDetailHTML[$key] = array_values( $tagOut );
}
echo json_encode($aDataTableDetailHTML);
这给了我输出:
[ [ "header", "content", "test" ], [ "header", "content", "test" ], [ "header", "content", "test" ] ]
这似乎与你所追求的相符。希望这会有所帮助。
我还测试了一些额外的值,该模式继续携带。
评论
0赞
Sergey B.
11/7/2018
这不适用于更简单的表。示例:1 2 3 - 标题 1 2 3 - 正文
2赞
Nigel Ren
11/7/2018
#2
我已经更改了很多代码以(希望)简化它。这分两个阶段工作,第一个阶段是提取元素并构建每行中所有元素的数组 - 将结果存储到 .<tr>
<td>
$rows
其次是通过遍历第一行,然后从所有行中提取相应的数据来垂直绑定数据......array_column()
$trList = $DOM->getElementsByTagName("tr");
$rows = [];
foreach ( $trList as $tr ) {
$row = [];
foreach ( $tr->getElementsByTagName("td") as $td ) {
$row[] = trim($td->textContent);
}
$rows[] = $row;
}
$aDataTableDetailHTML = [];
foreach ( $rows[0] as $col => $value ) {
$aDataTableDetailHTML[] = array_column($rows, $col);
}
echo json_encode($aDataTableDetailHTML);
其中测试数据给出了...
[["header","content","test"],["header","content","test"],["header","content","test"]]
0赞
csskevin
9/14/2019
#3
我知道这个答案来得很晚,但我为此目的开发了一个包。它被称为 TableDude。
对于您的情况,此PHP代码片段将起作用。
// Including TableDude
require __DIR__ . "/../src/autoload.php";
$html = "<html>
<head>
</head>
<body>
<table>
<tbody>
<tr>
<td>header</td>
<td>header</td>
<td>header</td>
</tr>
<tr>
<td>content</td>
<td>content</td>
<td>content</td>
</tr>
<tr>
<td>test</td>
<td>test</td>
<td>test</td>
</tr>
</tbody>
</table>
</body>
</html>";
// Parses the HTML to array table
$simpleParser = new \TableDude\Parser\SimpleParser($html);
$parsedTables = $simpleParser->parseHTMLTables();
if(count($parsedTables) > 0)
{
$firstTable = $parsedTables[0];
$tableOrderedByColumn = \TableDude\Tools\ArrayTool::swapArray($firstTable);
print_r($tableOrderedByColumn);
}
// This would output
/*
array(
array("header", "content", "test"),
array("header", "content", "test"),
array("header", "content", "test")
)
*/
0赞
mickmackusa
11/7/2023
#4
要维护行和单元格之间的父子关系,请在标记的上下文中访问标记。td
tr
通过将第一级键与第二级键交换来完成数据结构的转置。
代码:(演示)
$dom = new DOMDocument();
$dom->loadHTML($html);
$result = [];
foreach ($dom->getElementsByTagName('tr') as $i => $row) {
foreach ($row->getElementsByTagName('td') as $c => $cell) {
$result[$c][$i] = $cell->nodeValue;
}
}
var_export($result);
评论