I trying to insert a table in database, and I want to convert two rows in one array.
Can anyone help me out?
<table>
<tr class="pair"><td>1</td><td>2</td></tr>
<tr class="pair">td<>3</td><td>4</td></tr>
<tr class="unpair"><td>1</td><>2</td></tr>
<tr class="unpair"><td>3</td><td>4</td></tr>
</table>
<?php
require('simple_html_dom.php');
foreach($table->find('tr[class=pair') as $rowpair) {
$rowData = array();
foreach($rowpair->find('td') as $cell) {
$rowData[] = $cell->innertext;
}
foreach($table->find('tr[class=unpair') as $rowunpair) {
$rowData = array();
foreach($rowunpair->find('td') as $cell) {
$rowData[] = $cell->innertext;
}
?>
to obtain
<table>
<tr class="pair"><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr class="unpair"><td>1</td><td>2</td><td>3</td><td>4</td></tr>
</table>
This should work to group all table rows by class.
The basic logic is to loop through all the rows in a table and identify if it's seen that class before or not. If it hasn't, it'll store reference to that row as the 'canonical' row to use. If it has seen the class before, it will transfer over all it's children to the canonical row.
This approach should work for any number of tables in a blog and any set of class names.
<?php
$str = '<table><tr class="pair"><td>1</td><td>2</td></tr><tr class="pair"><td>3</td><td>4</td></tr><tr class="unpair"><td>1</td><td>2</td></tr><tr class="unpair"><td>3</td><td>4</td></tr>
</table>';
$doc = new DOMDocument();
$doc->loadHTML($str);
$tables = $doc->getElementsByTagName('table');
foreach ($tables as $table) {
#For each TR in the table, group into rows
$table_classes = array();
$rows = $table->getElementsByTagName('tr');
$row_list = array();
foreach ($rows as $row) {
array_push($row_list, $row);
}
for($i=0; $i<count($row_list); $i++){
$row = $row_list[$i];
$row_class = $row->getAttribute('class');
if(!array_key_exists($row_class, $table_classes)){
#if this is the for occurrence of that clase, store this row as the original_row
$table_classes[$row_class] = $row;
}else{
$original_row = $table_classes[$row_class];
#Move children over to original row
foreach ($row->childNodes as $child) {
$clone = $child->cloneNode(true);
$original_row->appendChild($clone);
}
#Now delete original
$row->parentNode->removeChild($row);
}
}
}
echo htmlspecialchars($doc->saveXML());
?>
Returns:
<table>
<tr class="pair">
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
<tr class="unpair">
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
</table>
Related
hi everybody i want to dom a webpage and fetch data from it's table.
table code :
<tbody>
<tr class="sh" onclick="ii.ShowShareHolder('21711,IRO1DMOR0004')">
<td>person</td>
<td><div class="ltr" title="1,100,000">1 M</div></td>
<td>2.050</td>
<td>0</td>
<td><div class=""></div></td>
</tr>
<tr class="sh" onclick="ii.ShowShareHolder('42123,IRO1DMOR0004')">
<td>person</td>
<td>953,169</td>
<td>1.780</td>
<td>0</td>
<td><div class=""></div></td>
</tr>
</tbody>
this table has two kind of data bigger than 1M and smaller than 1M . i want to get the 1.100.000 td div data and 953.169 data on this table.
my code is below.it works fine for bigger than 1M data but i don't know how to get the smaller data on this table.
foreach ($tables as $table) {
foreach ($table->find('tr') as $row) {
foreach($row->find('div') as $div)
{
if(array_key_exists('title',$div->attr))
{
$data[] = str_replace(",","",($div->attr['title']));
}
}
}
}
tnx man i use your code but it doesn't work and have many error.
this is my complete functions code.because the server is gzip encode i read with curl .
$url = "http://tsetmc.com/Loader.aspx?Partree=15131T&c=IRO1DMOR0004";
$curl = curl_get_data($url);
if(!empty($curl) ){
$html = str_get_html($curl);
$xml = simplexml_load_string($html);
var_dump($xml);
$data = [];
// For each <tr>
foreach ($xml->tr as $row) {
// check path `<td><div title="">`
$result = $row->xpath('td/div[#title]');
if (! empty($result)) {
foreach ($result as $item) {
$data[] = str_replace(',', '', $item['title']);
}
}
else {
// if not found, check the 2nd <td>
$result = $row->xpath('td[position()=2]');
foreach ($result as $item) {
$data[] = str_replace(',', '', $item);
}
}
}
return $data;
}
You could check if the <div title=""> exist. If true, get that value, else, get the value of the second <td>.
Here is an example using SimpleXML:
$html = <<<HTML
<tbody>
<tr class="sh" onclick="ii.ShowShareHolder('21711,IRO1DMOR0004')">
<td>person</td>
<td><div class="ltr" title="1,100,000">1 M</div></td>
<td>2.050</td>
<td>0</td>
<td><div class=""></div></td>
</tr>
<tr class="sh" onclick="ii.ShowShareHolder('42123,IRO1DMOR0004')">
<td>person</td>
<td>953,169</td>
<td>1.780</td>
<td>0</td>
<td><div class=""></div></td>
</tr>
</tbody>
HTML;
// parse HTML
$xml = simplexml_load_string($html);
$data = [];
// For each <tr>
foreach ($xml->tr as $row) {
// if not found, check the 2nd <td>
$item = $row->children()[1];
// check if a div with title exists
if (isset($item->div['title'])) {
$data[] = str_replace(',', '', $item->div['title']);
}
else { // else, take the content
$data[] = str_replace(',', '', $item);
}
}
var_dump($data);
Output:
array(2) {
[0]=>
string(7) "1100000"
[1]=>
string(6) "953169"
}
See the live demo.
I have an array of result after searching parameters,i want to print that result.while printing the result using foreach loop,i need to check the condition that ,if purchase dates are same, they should be printed in same row.How i can implement this?please help me.Thanks in advance
here is my code: ( i have get the result in controller and then i append the result in view)
foreach($res as $key => $row)
{
$i++;
$billfirst='';
$billend= $row['bill_date'];
if( $billfirst != $billend){
echo "<tr>
<td class='txt'> ".$i."</td>
<td class='txt'> ".$row['store']."</td>
<td class='txt'> ".$row['cust']."</td>
<td class='txt'> ".$row['name']."</td>
<td class='txt'> ".$row['net_amount']."</td>
<td class='txt'> ".$row['bill_date']."</td>
</tr>" ;
}
else {
echo "<tr><td class='txt'> ".$row['name']."</td>
<td class='txt'> ".$row['net_amount']."</td>
<td class='txt'> ".$row['bill_date']."</td>
</tr>";
}
$billfirst == $billend;
echo "</tbody></table>";
}
You need to make additional array to group your rows, example:
$arRows = array();
$billPrevious = "empty";
// save new grouped array
foreach($res as $key => $row) {
$arRows[$row['bill_date']][] = $row;
}
// show groups - in the way you want to group it visually in table
foreach ($arRows as $key => $arGroup) {
echo '<tr>';
$arName = '';
$arStore = '';
foreach ($arGroup as $keyInGroup => $row) {
$arName[] = $row['name'];
$arStore[] = $row['store'];
}
echo '<td>'.implode('<br>', $arName).'</td>';
echo '<td>'.implode('<br>', $arStore).'</td>';
echo '</tr>';
}
I'm trying to build divs based on unique values. So for each line, the script checks the team name against $tempTeam. If they're equal, the line gets added to the table in the existing div. If they're not equal, a new div and table is created, and the line is added there.
However, the if part isn't recognizing when $tempTeam is equal to the team so it never runs, even though the else part is properly setting $tempTeam. So I'm wondering why the variable is working for the else part of the code, but not the if part.
Here's the full code, although the trouble begins when I first define $tempTeam. Thanks for any help.
<?php
$csv = file_get_contents('schedules.csv');
$csv_array = explode("\n", $csv);
unset($csv_array[count($csv_array) - 1]);
$headers = explode(",", $csv_array[0]);
// iterate through all lines of CSV, skipping first header line
for($i=1;$i<count($csv_array);$i++) {
$line = explode(",", $csv_array[$i]);
// iterate through all headers and assign corresponding line value
foreach ($headers as $index => $header){
$parsed_array[$i][$header] = $line[$index];
}
}
// create divs and tables
$tempTeam = '';
foreach ($parsed_array as $i => $match) {
if ($tempTeam == $match['Team']) {
echo "
<tr><td>$match[Date]</td><td>$match[Result]</td><td>$match[Location]</td><td>$match[Opponent]</td></tr>
";
}
else if ($tempTeam == '') {
$tempTeam = $match['Team'];
echo "
<div class=\"schedule\" data-container=\"$match[League]\">
<table>
<thead>
<tr>
<th colspan=\"4\">$match[Team]</th>
</tr>
<tr>
<th>Date</th><th>Result</th><th>Location</th><th>Opponent</th>
</tr>
</thead>
<tbody>
<tr><td>$match[Date]</td><td>$match[Result]</td><td>$match[Location]</td><td>$match[Opponent]</td></tr>
";
}
else {
$tempTeam = $match['Team'];
echo "
</tbody>
</table>
</div>
<div class=\"schedule\" data-container=\"$match[League]\">
<table>
<thead>
<tr>
<th colspan=\"4\">$match[Team]</th>
</tr>
<tr>
<th>Date</th><th>Result</th><th>Location</th><th>Opponent</th>
</tr>
</thead>
<tbody>
<tr><td>$match[Date]</td><td>$match[Result]</td><td>$match[Location]</td><td>$match[Opponent]</td></tr>
";
}
}
echo "
</tbody>
</table>
</div>
";
?>
For a start, look at the first line of the else clause:
$tempTeam == $match['Team'];
I'm pretty certain that's not what you wanted to do, it seems to me that assignment would probably be a better choice than comparison.
What you're doing is no different to:
$a = 1;
$a == $a + 1;
print ($a);
which will still output 1 rather than 2. If you want do do assignment, it should have just the one = character:
$tempTeam = $match['Team'];
How can I get text from HTML table cells using PHP DOM query?
HTML table is:
<table>
<tr>
<th>Job Location:</th>
<td>Kabul
</td>
</tr>
<tr>
<th>Nationality:</th>
<td>Afghan</td>
</tr>
<tr>
<th>Category:</th>
<td>Program</td>
</tr>
</table>
I have following query but it doesn't work:
$xmlPageDom = new DomDocument();
#$xmlPageDom->loadHTML($html);
$xmlPageXPath = new DOMXPath($xmlPageDom);
$value = $xmlPageXPath->query('//table td /text()');
get a complete table with php domdocument and print it
The answer is like this:
$html = "<table ID='myid'><tr><td>1</td><td>2</td></tr><tr><td>4</td><td>5</td></tr><tr><td>7</td><td>8</td></tr></table>";
$xml = new DOMDocument();
$xml->validateOnParse = true;
$xml->loadHTML($html);
$xpath = new DOMXPath($xml);
$table =$xpath->query("//*[#id='myid']")->item(0);
$rows = $table->getElementsByTagName("tr");
foreach ($rows as $row) {
$cells = $row -> getElementsByTagName('td');
foreach ($cells as $cell) {
print $cell->nodeValue;
}
}
EDIT: Use this instead
$table = $xpath->query("//table")->item(0);
So I want to show in an 'echo' only the people that day which the situation is 'Yes', so let's assume today is only 'John' from my array list that have the situation 'Yes'.
$people = array('John', 'Greg', 'Mike', 'James', 'Jason');
$situation = array('Yes');
$html = str_get_html('<table class="mytab">
<tr>
<th>Name</th>
<th>Situation</th>
</tr>
<tr>
<td>
John
</td>
<td class="s">
<strong>Yes</strong>
</td>
</tr>
<tr>
<td>
Allan
</td>
<td class="s">
<strong>No</strong>
</td>
</tr>
<tr>
<td>
James
</td>
<td class="s">
<strong>No</strong>
</td>
</tr>
</table>');
$table = $html->find('table', 0);
$rowData = array();
foreach($table->find('tr') as $row) {
// initialize array to store the cell data from each row
$content= array();
foreach($row->find('td') as $cell) {
// push the cell's text to the array
$content[] = $cell->plaintext;
}
$rowData[] = $content;
}
echo '<table>';
foreach ($rowData as $row => $tr) {
echo '<tr>';
foreach ($tr as $td)
echo '<td>' . $td .'</td>';
echo '</tr>';
}
echo '</table>';
The code above is going to show:
John Yes
Allan No
James No
It's driving me insane I can't figure it out!!
How can I search in the <td>s and get only the people 'Yes' that day?
Assuming your $html is a valid XML string (meaning each tag closes properly, and has a parent tag, and no text outside tags), do this:
$html="<table>..";
$xml = new SimpleXmlElement($html);
$result=array();
foreach($xml->tr as $tr){
//you have your td, see what it has
$name='';
foreach($tr->td as $td) {
if(isset($td->a))
$name=$td->a;
if(isset($td->strong) && $td->strong=='Yes'){
$result[]=strval($name);
}
}
}
print_r($result); //this will have array with name of those where YES
Array
(
[0] => John
)
EDIT: , if you have a well-known XML format of the html, no need to go and check every td. Here I remove nested loop, and reducing complexity from O(n2) to O(n).
$result=array();
foreach($xml->tr as $tr){
//just in case see if a tag is there
if(isset($tr->td[0]->a))
$name = $tr->td[0]->a;
$td2 = $tr->td[1];
if(isset($td2->strong) && $td2->strong=='Yes'){
$result[]=strval($name);
}
}
print_r($result);