HTML 简单解析器如何在 For each 循环中跳过 td 中的 tr
HTML simple parser How to skip a tr inside a td in For each loop
我有一个 html 这样的内容...
$html = <<<EOF
<table id="specialTbl">
<tbody>
<tr>
<td> row-1-td-1</td>
<td> row-1-td-2</td>
<td> row-1-td-3</td>
<td>
<table class="runsOn"> // Problem starts here
<tbody>
<tr>
<td>row-1-td-4-Child-1</td>
<td>row-1-td-4-Child-2</td>
</tr>
</tbody>
</table>
</td>
<td> row-1-td-5</td>
<td> row-1-td-6</td>
</tr>
<tr>
<td> row-2-td-1</td>
<td> row-2-td-2</td>
<td> row-2-td-3</td>
<td>
<table class="runsOn">
<tbody>
<tr>
<td>row-2-td-4-Child-1</td>
<td>row-2-td-4-Child-2</td>
</tr>
</tbody>
</table>
</td>
<td> row-2-td-5</td>
<td> row-2-td-6</td>
</tr>
<tr>
<td> row-3-td-1</td>
<td> row-3-td-2</td>
<td> row-3-td-3</td>
<td>
<table class="runsOn">
<tbody>
<tr>
<td>row-3-td-4-Child-1</td>
<td>row-3-td-4-Child-2</td>
</tr>
</tbody>
</table>
</td>
<td> row-3-td-5</td>
<td> row-3-td-6</td>
</tr>
<tr>
<td> row-4-td-1</td>
<td> row-4-td-2</td>
<td> row-4-td-3</td>
<td>
<table class="runsOn">
<tbody>
<tr>
<td>row-4-td-4-Child-1</td>
<td>row-4-td-4-Child-2</td>
</tr>
</tbody>
</table>
</td>
<td> row-4-td-5</td>
<td> row-4-td-6</td>
</tr>
<tr>
<td> row-5-td-1</td>
<td> row-5-td-2</td>
<td> row-5-td-3</td>
<td>
<table class="runsOn">
<tbody>
<tr>
<td>row-5-td-4-Child-1</td>
<td>row-5-td-4-Child-2</td>
</tr>
</tbody>
</table>
</td>
<td> row-5-td-5</td>
<td> row-5-td-6</td>
</tr>
<tr>
<td> row-6-td-1</td>
<td> row-6-td-2</td>
<td> row-6-td-3</td>
<td>
<table class="runsOn">
<tbody>
<tr>
<td>row-6-td-4-Child-1</td>
<td>row-6-td-4-Child-2</td>
</tr>
</tbody>
</table>
</td>
<td> row-6-td-5</td>
<td> row-6-td-6</td>
</tr>
<tr>
<td> row-7-td-1</td>
<td> row-7-td-2</td>
<td> row-7-td-3</td>
<td>
<table class="runsOn">
<tbody>
<tr>
<td>row-7-td-4-Child-1</td>
<td>row-7-td-4-Child-2</td>
</tr>
</tbody>
</table>
</td>
<td> row-7-td-5</td>
<td> row-7-td-6</td>
</tr>
</tbody>
</table>
EOF;
$html= str_get_html($html);
$table =$html->find('table#specialTbl',0) ;
$response["response_code"] = 200;
$response["rows"] = array();
foreach($table->find('tr') as $key=>$value) {
$post["td1"]= trim(strip_tags($value->find('td',0)->plaintext));
$post["td2"]= trim(strip_tags($value->find('td',1)->plaintext));
$post["td3"]= trim(strip_tags($value->find('td',2)->plaintext));
$post["td4"]= trim(strip_tags($value->find('td',3)->plaintext));
$post["td5"]= trim(strip_tags($value->find('td',4)->plaintext));
$post["td6"]= trim(strip_tags($value->find('td',5)->plaintext));
array_push($response["rows"], $post);
}
$json = json_encode($response);
echo $json_content;
并且Json响应是
{
"response_code":200,
"rows":[
{
"td1":"row-1-td-1",
"td2":"row-1-td-2",
"td3":"row-1-td-3",
"td4":"row-1-td-4-Child-1 row-1-td-4-Child-2",
"td5":"row-1-td-4-Child-1",
"td6":"row-1-td-4-Child-2"
},
{
"td1":"row-1-td-4-Child-1",
"td2":"row-1-td-4-Child-2",
"td3":"",
"td4":"",
"td5":"",
"td6":""
},
{
"td1":"row-2-td-1",
"td2":"row-2-td-2",
"td3":"row-2-td-3",
"td4":"row-2-td-4-Child-1 row-2-td-4-Child-2",
"td5":"row-2-td-4-Child-1",
"td6":"row-2-td-4-Child-2"
},
{
"td1":"row-2-td-4-Child-1",
"td2":"row-2-td-4-Child-2",
"td3":"",
"td4":"",
"td5":"",
"td6":""
},
{
"td1":"row-3-td-1",
"td2":"row-3-td-2",
"td3":"row-3-td-3",
"td4":"row-3-td-4-Child-1 row-3-td-4-Child-2",
"td5":"row-3-td-4-Child-1",
"td6":"row-3-td-4-Child-2"
},
{
"td1":"row-3-td-4-Child-1",
"td2":"row-3-td-4-Child-2",
"td3":"",
"td4":"",
"td5":"",
"td6":""
},
{
"td1":"row-4-td-1",
"td2":"row-4-td-2",
"td3":"row-4-td-3",
"td4":"row-4-td-4-Child-1 row-4-td-4-Child-2",
"td5":"row-4-td-4-Child-1",
"td6":"row-4-td-4-Child-2"
},
{
"td1":"row-4-td-4-Child-1",
"td2":"row-4-td-4-Child-2",
"td3":"",
"td4":"",
"td5":"",
"td6":""
},
{
"td1":"row-5-td-1",
"td2":"row-5-td-2",
"td3":"row-5-td-3",
"td4":"row-5-td-4-Child-1 row-5-td-4-Child-2",
"td5":"row-5-td-4-Child-1",
"td6":"row-5-td-4-Child-2"
},
{
"td1":"row-5-td-4-Child-1",
"td2":"row-5-td-4-Child-2",
"td3":"",
"td4":"",
"td5":"",
"td6":""
},
{
"td1":"row-6-td-1",
"td2":"row-6-td-2",
"td3":"row-6-td-3",
"td4":"row-6-td-4-Child-1 row-6-td-4-Child-2",
"td5":"row-6-td-4-Child-1",
"td6":"row-6-td-4-Child-2"
},
{
"td1":"row-6-td-4-Child-1",
"td2":"row-6-td-4-Child-2",
"td3":"",
"td4":"",
"td5":"",
"td6":""
},
{
"td1":"row-7-td-1",
"td2":"row-7-td-2",
"td3":"row-7-td-3",
"td4":"row-7-td-4-Child-1 row-7-td-4-Child-2",
"td5":"row-7-td-4-Child-1",
"td6":"row-7-td-4-Child-2"
},
{
"td1":"row-7-td-4-Child-1",
"td2":"row-7-td-4-Child-2",
"td3":"",
"td4":"",
"td5":"",
"td6":""
}
]
}
foreach
有问题。我怎样才能跳过 td
中的 tr
。我在 table 中有 7 行,id "specialTbl"。但是 for each
returns json 中的 14 行,因为它循环通过 table 称为 runsOn。
如何避免在 td(4th)
中循环遍历 table
您可以使用 PHP's DOM parser,并且在搜索 tr
项之前,让它从 HTML 结构中删除所有嵌套表:
// Parse the HTML into a DOM object & find the table by ID
$doc = new DOMDocument();
$doc->loadHTML($html);
$table = $doc->getElementById('specialTbl');
// Remove all nested TRs from the DOM table object
$nested = $table->getElementsByTagName('table');
foreach ($nested as $element)
{
// Remove the TRs from thi nested table
foreach ($element->getElementsByTagName('tr') as $tr)
$tr->parentNode->removeChild($tr);
}
// Now when we search through TRs, we only get the top level ones
$rows = $table->getElementsByTagName('tr');
$response = array();
foreach ($rows as $row)
{
// Collect the values of this row's TDs
$tds = array();
foreach ($row->getElementsByTagName('td') as $td)
{
$tds[] = trim($td->nodeValue);
}
// Add this row to the response
$response['rows'][] = $tds;
}
// Add extra response details
$response['response_code'] = 200; // You shouldn't need to explicitly send this
$json = json_encode($response);
// Output JSON
header('Content-type: application/json'); // Use the correct MIME type
echo $json;
按如下方式将 DomDocument 与 Xpath 一起使用会更容易。 PHP5 中已经存在 DomDocument。它会给你想要的输出。
$doc = new DOMDocument();
$doc->loadHTML($html);
$xpath = new DOMXpath($doc);
$response["response_code"] = 200;
$response["rows"] = array();
$trs = $xpath->query("//table[@id='specialTbl']/tbody/tr"); // all child tr's in all child tbody's in any table that has id 'specialTbl'
foreach ($trs as $tr) {
$post = array();
$tds = $xpath->query("td", $tr); // all child td's in $tr
foreach ($tds as $key => $td) {
$post["td" . ++$key] = $td->textContent;
}
array_push($response["rows"], $post);
}
$json_content = json_encode($response);
echo $json_content;
但您也可以继续使用 http://simplehtmldom.sourceforge.net/manual.htm 并使用类似 css 的选择器(未经测试的代码,我没有 simplehtmldom):
$html= str_get_html($html);
$response["response_code"] = 200;
$response["rows"] = array();
$trs = $html->find("table#specialTbl>tbody>tr");
foreach ($trs as $tr) {
$post = array();
$tds = $tr->children();
foreach ($tds as $key => $td) {
$post["td" . ++$key] = $td->innertext;
}
array_push($response["rows"], $post);
}
$json_content = json_encode($response);
echo $json_content;
我有一个 html 这样的内容...
$html = <<<EOF
<table id="specialTbl">
<tbody>
<tr>
<td> row-1-td-1</td>
<td> row-1-td-2</td>
<td> row-1-td-3</td>
<td>
<table class="runsOn"> // Problem starts here
<tbody>
<tr>
<td>row-1-td-4-Child-1</td>
<td>row-1-td-4-Child-2</td>
</tr>
</tbody>
</table>
</td>
<td> row-1-td-5</td>
<td> row-1-td-6</td>
</tr>
<tr>
<td> row-2-td-1</td>
<td> row-2-td-2</td>
<td> row-2-td-3</td>
<td>
<table class="runsOn">
<tbody>
<tr>
<td>row-2-td-4-Child-1</td>
<td>row-2-td-4-Child-2</td>
</tr>
</tbody>
</table>
</td>
<td> row-2-td-5</td>
<td> row-2-td-6</td>
</tr>
<tr>
<td> row-3-td-1</td>
<td> row-3-td-2</td>
<td> row-3-td-3</td>
<td>
<table class="runsOn">
<tbody>
<tr>
<td>row-3-td-4-Child-1</td>
<td>row-3-td-4-Child-2</td>
</tr>
</tbody>
</table>
</td>
<td> row-3-td-5</td>
<td> row-3-td-6</td>
</tr>
<tr>
<td> row-4-td-1</td>
<td> row-4-td-2</td>
<td> row-4-td-3</td>
<td>
<table class="runsOn">
<tbody>
<tr>
<td>row-4-td-4-Child-1</td>
<td>row-4-td-4-Child-2</td>
</tr>
</tbody>
</table>
</td>
<td> row-4-td-5</td>
<td> row-4-td-6</td>
</tr>
<tr>
<td> row-5-td-1</td>
<td> row-5-td-2</td>
<td> row-5-td-3</td>
<td>
<table class="runsOn">
<tbody>
<tr>
<td>row-5-td-4-Child-1</td>
<td>row-5-td-4-Child-2</td>
</tr>
</tbody>
</table>
</td>
<td> row-5-td-5</td>
<td> row-5-td-6</td>
</tr>
<tr>
<td> row-6-td-1</td>
<td> row-6-td-2</td>
<td> row-6-td-3</td>
<td>
<table class="runsOn">
<tbody>
<tr>
<td>row-6-td-4-Child-1</td>
<td>row-6-td-4-Child-2</td>
</tr>
</tbody>
</table>
</td>
<td> row-6-td-5</td>
<td> row-6-td-6</td>
</tr>
<tr>
<td> row-7-td-1</td>
<td> row-7-td-2</td>
<td> row-7-td-3</td>
<td>
<table class="runsOn">
<tbody>
<tr>
<td>row-7-td-4-Child-1</td>
<td>row-7-td-4-Child-2</td>
</tr>
</tbody>
</table>
</td>
<td> row-7-td-5</td>
<td> row-7-td-6</td>
</tr>
</tbody>
</table>
EOF;
$html= str_get_html($html);
$table =$html->find('table#specialTbl',0) ;
$response["response_code"] = 200;
$response["rows"] = array();
foreach($table->find('tr') as $key=>$value) {
$post["td1"]= trim(strip_tags($value->find('td',0)->plaintext));
$post["td2"]= trim(strip_tags($value->find('td',1)->plaintext));
$post["td3"]= trim(strip_tags($value->find('td',2)->plaintext));
$post["td4"]= trim(strip_tags($value->find('td',3)->plaintext));
$post["td5"]= trim(strip_tags($value->find('td',4)->plaintext));
$post["td6"]= trim(strip_tags($value->find('td',5)->plaintext));
array_push($response["rows"], $post);
}
$json = json_encode($response);
echo $json_content;
并且Json响应是
{
"response_code":200,
"rows":[
{
"td1":"row-1-td-1",
"td2":"row-1-td-2",
"td3":"row-1-td-3",
"td4":"row-1-td-4-Child-1 row-1-td-4-Child-2",
"td5":"row-1-td-4-Child-1",
"td6":"row-1-td-4-Child-2"
},
{
"td1":"row-1-td-4-Child-1",
"td2":"row-1-td-4-Child-2",
"td3":"",
"td4":"",
"td5":"",
"td6":""
},
{
"td1":"row-2-td-1",
"td2":"row-2-td-2",
"td3":"row-2-td-3",
"td4":"row-2-td-4-Child-1 row-2-td-4-Child-2",
"td5":"row-2-td-4-Child-1",
"td6":"row-2-td-4-Child-2"
},
{
"td1":"row-2-td-4-Child-1",
"td2":"row-2-td-4-Child-2",
"td3":"",
"td4":"",
"td5":"",
"td6":""
},
{
"td1":"row-3-td-1",
"td2":"row-3-td-2",
"td3":"row-3-td-3",
"td4":"row-3-td-4-Child-1 row-3-td-4-Child-2",
"td5":"row-3-td-4-Child-1",
"td6":"row-3-td-4-Child-2"
},
{
"td1":"row-3-td-4-Child-1",
"td2":"row-3-td-4-Child-2",
"td3":"",
"td4":"",
"td5":"",
"td6":""
},
{
"td1":"row-4-td-1",
"td2":"row-4-td-2",
"td3":"row-4-td-3",
"td4":"row-4-td-4-Child-1 row-4-td-4-Child-2",
"td5":"row-4-td-4-Child-1",
"td6":"row-4-td-4-Child-2"
},
{
"td1":"row-4-td-4-Child-1",
"td2":"row-4-td-4-Child-2",
"td3":"",
"td4":"",
"td5":"",
"td6":""
},
{
"td1":"row-5-td-1",
"td2":"row-5-td-2",
"td3":"row-5-td-3",
"td4":"row-5-td-4-Child-1 row-5-td-4-Child-2",
"td5":"row-5-td-4-Child-1",
"td6":"row-5-td-4-Child-2"
},
{
"td1":"row-5-td-4-Child-1",
"td2":"row-5-td-4-Child-2",
"td3":"",
"td4":"",
"td5":"",
"td6":""
},
{
"td1":"row-6-td-1",
"td2":"row-6-td-2",
"td3":"row-6-td-3",
"td4":"row-6-td-4-Child-1 row-6-td-4-Child-2",
"td5":"row-6-td-4-Child-1",
"td6":"row-6-td-4-Child-2"
},
{
"td1":"row-6-td-4-Child-1",
"td2":"row-6-td-4-Child-2",
"td3":"",
"td4":"",
"td5":"",
"td6":""
},
{
"td1":"row-7-td-1",
"td2":"row-7-td-2",
"td3":"row-7-td-3",
"td4":"row-7-td-4-Child-1 row-7-td-4-Child-2",
"td5":"row-7-td-4-Child-1",
"td6":"row-7-td-4-Child-2"
},
{
"td1":"row-7-td-4-Child-1",
"td2":"row-7-td-4-Child-2",
"td3":"",
"td4":"",
"td5":"",
"td6":""
}
]
}
foreach
有问题。我怎样才能跳过 td
中的 tr
。我在 table 中有 7 行,id "specialTbl"。但是 for each
returns json 中的 14 行,因为它循环通过 table 称为 runsOn。
如何避免在 td(4th)
中循环遍历 table您可以使用 PHP's DOM parser,并且在搜索 tr
项之前,让它从 HTML 结构中删除所有嵌套表:
// Parse the HTML into a DOM object & find the table by ID
$doc = new DOMDocument();
$doc->loadHTML($html);
$table = $doc->getElementById('specialTbl');
// Remove all nested TRs from the DOM table object
$nested = $table->getElementsByTagName('table');
foreach ($nested as $element)
{
// Remove the TRs from thi nested table
foreach ($element->getElementsByTagName('tr') as $tr)
$tr->parentNode->removeChild($tr);
}
// Now when we search through TRs, we only get the top level ones
$rows = $table->getElementsByTagName('tr');
$response = array();
foreach ($rows as $row)
{
// Collect the values of this row's TDs
$tds = array();
foreach ($row->getElementsByTagName('td') as $td)
{
$tds[] = trim($td->nodeValue);
}
// Add this row to the response
$response['rows'][] = $tds;
}
// Add extra response details
$response['response_code'] = 200; // You shouldn't need to explicitly send this
$json = json_encode($response);
// Output JSON
header('Content-type: application/json'); // Use the correct MIME type
echo $json;
按如下方式将 DomDocument 与 Xpath 一起使用会更容易。 PHP5 中已经存在 DomDocument。它会给你想要的输出。
$doc = new DOMDocument();
$doc->loadHTML($html);
$xpath = new DOMXpath($doc);
$response["response_code"] = 200;
$response["rows"] = array();
$trs = $xpath->query("//table[@id='specialTbl']/tbody/tr"); // all child tr's in all child tbody's in any table that has id 'specialTbl'
foreach ($trs as $tr) {
$post = array();
$tds = $xpath->query("td", $tr); // all child td's in $tr
foreach ($tds as $key => $td) {
$post["td" . ++$key] = $td->textContent;
}
array_push($response["rows"], $post);
}
$json_content = json_encode($response);
echo $json_content;
但您也可以继续使用 http://simplehtmldom.sourceforge.net/manual.htm 并使用类似 css 的选择器(未经测试的代码,我没有 simplehtmldom):
$html= str_get_html($html);
$response["response_code"] = 200;
$response["rows"] = array();
$trs = $html->find("table#specialTbl>tbody>tr");
foreach ($trs as $tr) {
$post = array();
$tds = $tr->children();
foreach ($tds as $key => $td) {
$post["td" . ++$key] = $td->innertext;
}
array_push($response["rows"], $post);
}
$json_content = json_encode($response);
echo $json_content;