<table>
<tr>
<th>Year</th>
<th>Score</th>
</tr>
<tr>
<td>2014</td>
<td>3078</td>
</tr>
</table>
If I have the above table being successfully stored as a variable, how could I append it to a div with an overflow-x style attribute?
I've tried the following snippet but no cigar:
$div = str_get_html('<div style="overflow-x:auto;"></div>');
$div = $div->find('div');
$div = $div->appendChild($table);
return $div;
so expected output should be:
<div style="overflow-x:auto;">
<table>
<tr>
<th>Year</th>
<th>Score</th>
</tr>
<tr>
<td>2014</td>
<td>3078</td>
</tr>
</table>
</div>
Hope this one will give you a basic idea of implementation. Here we are using DOMDocument.
Try this code snippet here
<?php
ini_set('display_errors', 1);
//creating table node
$tableNode='<table><tr><th>Year</th><th>Score</th></tr><tr><td>2014</td><td>3078</td></tr></table>';
$domDocument = new DOMDocument();
$domDocument->encoding="UTF-8";
$domDocument->loadHTML($tableNode);
$domXPath = new DOMXPath($domDocument);
$table = $domXPath->query("//table")->item(0);
//creating empty div node.
$domDocument = new DOMDocument();
$element=$domDocument->createElement("div");
$element->setAttribute("style", "overflow-x:auto;");
$result=$domDocument->importNode($table,true);//importing node from of other DOMDocument
$element->appendChild($result);
echo $domDocument->saveHTML($element);
Related
How can I merge the date td/cell into the time td/cell?
I would like the table row to consist of 3 cells, the middle cell should read date time.
My Code:
$dom = new DOMDocument;
$dom->loadHTMLFile("test.html");
$dom->validateOnParse = true;
$xpath = new DOMXPath($dom);
$table = $xpath->query("//*[#class='mytable']//tbody")->item(0);
$td = $table->getElementsbytagname("td");
test.html file contents:
<table class="mytable">
<tbody><tr>
<td>date</td>
<td>td1</td>
<td>time</td>
<td>td2</td>
</tr></tbody>
</table>
Desired result:
<table class="mytable">
<tbody><tr>
<td>td1</td>
<td>date time</td>
<td>td2</td>
</tr></tbody>
</table>
Collect the tbody tr cells. Overwrite the 3rd occurring cell's text using the 1st occurring cell' text, then delete the first cell.
Code (Demo)
$html = <<<HTML
<table class="mytable">
<tbody><tr>
<td>date</td>
<td>td1</td>
<td>time</td>
<td>td2</td>
</tr></tbody>
</table>
HTML;
$dom = new DOMDocument;
$dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$xpath = new DOMXPath($dom);
foreach ($xpath->query("//table[#class='mytable']/tbody/tr") as $tr) {
$tds = $tr->getElementsByTagName("td");
$tds->item(2)->nodeValue = $tds->item(0)->nodeValue .
' ' . $tds->item(2)->nodeValue;
$tr->removeChild($tds->item(0));
}
echo $dom->saveHTML();
Output:
<table class="mytable">
<tbody><tr>
<td>td1</td>
<td>date time</td>
<td>td2</td>
</tr></tbody>
</table>
I have some PHP code which returns the HTML content from another file:
$html = file_get_contents('myFile.html');
$dom = new DOMDocument();
$dom->loadHTML($html);
This is a part of the content of $html:
<table class="content_table">
<tbody>
<tr>
<td>Value1</td>
<td>Value2</td>
<td>Value3</td>
</tr>
<tr>
<td>Value1</td>
<td>Value2</td>
<td>Value3</td>
</tr>
</tbody>
</table>
My question:
How can I get all the values of <td> where the table tag has the class "content_table"?
The following query looks for table element that has content_table class, then extracts the td values from it:
<?php
$html = '<table class="content_table">
<tbody>
<tr>
<td>Value1</td>
<td>Value2</td>
<td>Value3</td>
</tr>
<tr>
<td>Value1</td>
<td>Value2</td>
<td>Value3</td>
</tr>
</tbody>
</table>';
$dom = new DOMDocument('1.0', 'UTF-8');
$dom->loadHTML($html);
$xpath = new DOMXPath($dom);
$data = [];
foreach($xpath->query('//table[#class="content_table"]') as $table) {
foreach($table->getElementsByTagName('td') as $td) {
$data[] = $td->nodeValue;
}
}
print_r($data);
Or if you need only td elements that have content_table class then it do the task:
foreach($xpath->query('//td[#class="content_table"]') as $td) {
$data[] = $td->nodeValue;
}
Example html:
$html = '<table class="content_table">
<tbody>
<tr>
<td>Value1</td>
<td class="content_table">Value2</td>
<td>Value3</td>
</tr>
<tr>
<td>Value1</td>
<td class="content_table">Value2</td>
<td>Value3</td>
</tr>
</tbody>
</table>';
I have a html like below:
<table>
<thead>
<tr>
<th>Name</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr>
<td>ABC</td>
<td><a data-permission="allow"></a></td>
</tr>
<tr>
<td>B</td>
<td><a data-permission="allow"></a></td>
</tr>
<tr>
<td>C</td>
<td><a data-permission="allow"></a></td>
</tr>
<tr>
<td>D</td>
<td><a data-permission="allow"></a></td>
</tr>
<tr>
<td>E</td>
<td><button type="button" data-permission="allow"></button></td>
</tr>
</tbody>
</table>
Now i am finding the nodes who contains "data-permission" attributes like (a, button etc.) from above example.
TO do that i am using the below code. Now what i am trying do is remove that whole <a>..</a> or <button>...</button> or any other element if they contain "data-permission" attribute and after deletion only return remaining HTML. So how to achieve that?
$dom = new DOMDocument;
$dom->loadHTML($output);
$xpath = new DOMXPath($dom);
$nodes = $xpath->query('//#data-permission-id');
foreach ($nodes as $node) {
echo $node->nodeValue;
//$node->parentNode->removeChild($node); throws the error "Not Found Error"
}
Note- I have tried $node->parentNode->removeChild($node); inside loop, but it throws the error. Also after delete that tag, i want to get remaining HTML. I have read the How to delete element with DOMDocument? but it doesn't help.
Replace your node value to remove : $node->nodeValue = "";
$dom = new DOMDocument;
$dom->loadHTML($output);
echo "Previous : ".PHP_EOL.$dom->textContent.PHP_EOL;
$xpath = new DOMXPath($dom);
$nodes = $xpath->query("//*[#data-permission='allow']");
foreach ($nodes as $node) {
$node->nodeValue = "";
$dom->saveHTML();
}
Live demo : https://eval.in/885719
Live demo with your table data : https://eval.in/885780
I have this table in output from a program (string converted in a DomDocument in PHP):
<table>
<tr>
<td width="50">Â </td>
<td>My content</td>
<td width="50">Â </td>
</tr>
<table>
I need to remove the two tag <td width="50">Â </td> (i don't know why the program adds them, but there are -.-") like this:
<table>
<tr>
<td>My content</td>
</tr>
<table>
What's the best way for do it in PHP?
Edit:
the program is JasperReport Server. I call the report rendering function via web application:
//this is the call to server library for generate the report
$reportGen = $reportServer->runReport($myReport);
$domDoc = new \DomDocument();
$domDoc->loadHTML($reportGen);
return $domDoc->saveHTML($domDoc->getElementsByTagName('table')->item(0));
return the upper table who i need to fix...
Try this
<?php
$domDoc = new DomDocument();
$domDoc->loadHTML($reportGen);
$xpath = new DOMXpath($domDoc);
$tags = $xpath->query('//td');
foreach($tags as $tag) {
$value = $tag->nodeValue;
if(preg_match('/^(Â )/',$value))
$tag->parentNode->removeChild($tag);
}
?>
Regex and replace:
$var = '<table>
<tr>
<td width="50">Ã</td>
<td>My interssing content</td>
<td width="50">Ã</td>
</tr>
<table>';
$final = preg_replace('#(<td width="50".*?>).*?(</td>)#', '$1$2', $var);
$final = str_replace('<td width="50"></td>', '', $final);
echo $final;
Lately I've had a question, what I'm trying to do is read data from an HTML table and grab the data into a variable called $id. For example I have this code:
<tr>
<td>413</td>
<td>Party Hat</td>
<td>0</td>
<td>No</td>
<td>View SWF</td>
</tr>
What I want to do is that another variable called $array[$i] which is holding a search query. I want my PHP code to search through the table until it finds the section with that specific query in it. In this case is would be "Party Hat." What I want it to do after it finds the query is for it to look at the ID which is the "td" section above the name "Party Hat" the ID in this case is 413. After this I want the variable $id to hold the ID. How do I do this? Any help would be HIGHLY appreciated!
using Tidy, DOMDocument and DOMXPath (make sure the PHP extensions are enabled) you can do something like this:
<?php
$url = "http://example.org/test.html";
function get_data_from_table($id, $url)
{
// retrieve the content of that url
$content = file_get_contents($url);
// repair bad HTML
$tidy = tidy_parse_string($content);
$tidy->cleanRepair();
$content = (string)$tidy;
// load into DOM
$dom = new DOMDocument();
$dom->loadHTML($content);
// make xpath-able
$xpath = new DOMXPath($dom);
// search for the first td of each tr, where its content is $id
$query = "//tr/td[position()=1 and normalize-space(text())='$id']";
$elements = $xpath->query($query);
if ($elements->length != 1) {
// not exactly 1 result as expected? return number of hits
return $elements->length;
}
// our td was found
$element = $elements->item(0);
// get his parent element (tr)
$tr = $element->parentNode;
$data = array();
// iterate over it's td elements
foreach ($tr->getElementsByTagName("td") as $td) {
// retrieve the content as text
$data[] = $td->textContent;
}
// return the array of <td> contents
return $data;
}
echo '<pre>';
print_r(
get_data_from_table(
414,
$url
)
);
echo '</pre>';
Your HTML source (http://example.org/test.html):
<table><tr>
<td>413</td>
<td>Party Hat</td>
<td>0</td>
<td>No</td>
<td>View SWF</td>
</tr><tr>
<td>414</td>
<td>Party Hat</td>
<td>0</td>
<td>No</td>
<td>View SWF</td>
</tr>
(as you can see, no valid HTML, but this doesn't matter)
This works: (although a bit ugly, perhaps someone else can come up with a better xpath solution)
$html = <<<HTML
<html>
<body>
<table>
<thead>
<tr>
<td>id</td>
<td>name</td>
<td>a</td>
<td>b</td>
<td>c</td>
</tr>
</thead>
<tbody>
<tr>
<td>413</td>
<td>Party Hat</td>
<td>0</td>
<td>No</td>
<td>a link</td>
</tr>
<tr>
<td>414</td>
<td>Party Hat 2</td>
<td>0</td>
<td>No</td>
<td>a link</td>
</tr>
</tbody>
</table>
</body>
</html>
HTML;
$doc = new DOMDocument();
$doc->loadHTML($html);
$domxpath = new DOMXPath($doc);
$res = $domxpath->query("//*[local-name() = 'td'][text() = 'Party Hat']/../td[position() = '1']");
var_dump($res->length, $res->item(0)->textContent);
Outputs:
int(1)
string(3) "413"
try to load the html into an new DOMDocument via loadHTML and process it like an XML Doc, with xpath or other types of query