I have the PHP output, which is in table form, and I want that output in CSV format. How can I get that using PHP Smarty?
You should parse that PHP output with an xml parser. Use something like:
$phpOutput = ... ; //this is the output containing only the table
$xml = simplexml_load_string($phpOutput);
$csvOutput = "";
foreach ($xml->tr as $rows)
{
$cells = array();
foreach ($rows->td as $cell)
{
$cells[] = (string)$cell;
}
$csvOutput .= implode(",",$cells)."\r\n";
}
$smarty->assign("csv",$csvOutput);
Of course you must be careful and close every tag if you don't want to get warnings.
Related
I have never used XML before and am trying to loop through the XML and display all the display names in the 'A Team'. The code I am using is outputting 10 zeros and not the names.
The code I am using is attached below along with the feed.
Any assistance is much appreciated!
feed: https://apn.apcentiaservices.co.uk/ContactXML/agentfeed?organisation=se724de89ca150f
<?php
$url = 'https://apn.apcentiaservices.co.uk/ContactXML/agentfeed?organisation=se724de89ca150f';
$html = "";
$xml = simplexml_load_file($url);
for($i = 0; $i < 10; $i++){
$title = $xml->organisation['APN']->brand['AllStar Psychics']->pool['A Team']->agent[$i]->display-name;
echo $title;
}
echo $html;
?>
This might getthe basics you asked for. Not sure if it's what you want. I'm not that good at xpath.
$mydata = $xml->xpath('/organisation/brand/pool[#name="A Team"]//display-name');
foreach($mydata as $key=>$value){
echo('Name:' . $value .'<br>');
}
i really want to know if there is any php method can load an php document and execute it as html , then navigate trough the file to get the first tag element table , some thing like this
PS : the records in the table are getting from mysql query in the
server
$dom = new DOMDocument();
$dom->loadHTMLFile("figures.php");
$tables = $dom->getElementsByTagName('table');
$table = $tables->item(0);
foreach ($table->childNodes as $td) {
if ($td->nodeName == 'td') {
echo $td->nodeValue, "\n";
}
}
You can use the overflow buffer to first execute the php and load the output into a varable,
with your new variable you could get the content between X an Y
This is the first step; you get the output from the php into a variable:
ob_start();
include('phpfile.php');
$output=ob_end_clean();
Next step would be to go thru the output and only get the content you are interested in
Something like:
function GetBetween($content,$start,$end){
$r = explode($start, $content);
if (isset($r[1])){
$r = explode($end, $r[1]);
return $r[0];
}
return '';
}
echo GetBetween($output,"<table>","</table>");
Would echo the table.
Use SimpleXML
$xml= simplexml_load_file('figures.php');
$tables = $xml->xpath('//table[1]'); // only the first table
$table = $tables[0];
I am trying to parse the table shown here into a multi-dimensional php array. I am using the following code but for some reason its returning an empty array. After searching around on the web, I found this site which is where I got the parseTable() function from. From reading the comments on that website, I see that the function works perfectly. So I'm assuming there is something wrong with the way I'm getting the HTML code from file_get_contents(). Any thoughts on what I'm doing wrong?
<?php
$data = file_get_contents('http://flow935.com/playlist/flowhis.HTM');
function parseTable($html)
{
// Find the table
preg_match("/<table.*?>.*?<\/[\s]*table>/s", $html, $table_html);
// Get title for each row
preg_match_all("/<th.*?>(.*?)<\/[\s]*th>/", $table_html[0], $matches);
$row_headers = $matches[1];
// Iterate each row
preg_match_all("/<tr.*?>(.*?)<\/[\s]*tr>/s", $table_html[0], $matches);
$table = array();
foreach($matches[1] as $row_html)
{
preg_match_all("/<td.*?>(.*?)<\/[\s]*td>/", $row_html, $td_matches);
$row = array();
for($i=0; $i<count($td_matches[1]); $i++)
{
$td = strip_tags(html_entity_decode($td_matches[1][$i]));
$row[$row_headers[$i]] = $td;
}
if(count($row) > 0)
$table[] = $row;
}
return $table;
}
$output = parseTable($data);
print_r($output);
?>
I want my output array to look something like this:
1
--> 11:33AM
--> DEV
--> IN THE DARK
2
--> 11:29AM
--> LIL' WAYNE
--> SHE WILL
3
--> 11:26AM
--> KARDINAL OFFISHALL
--> NUMBA 1 (TIDE IS HIGH)
Don't cripple yourself parsing HTML with regexps! Instead, let an HTML parser library worry about the structure of the markup for you.
I suggest you to check out Simple HTML DOM (http://simplehtmldom.sourceforge.net/). It is a library specifically written to aid in solving this kind of web scraping problems in PHP. By using such a library, you can write your scraping in much less lines of code without worrying about creating working regexps.
In principle, with Simple HTML DOM you just write something like:
$html = file_get_html('http://flow935.com/playlist/flowhis.HTM');
foreach($html->find('tr') as $row) {
// Parse table row here
}
This can be then extended to capture your data in some format, for instance to create an array of artists and corresponding titles as:
<?php
require('simple_html_dom.php');
$table = array();
$html = file_get_html('http://flow935.com/playlist/flowhis.HTM');
foreach($html->find('tr') as $row) {
$time = $row->find('td',0)->plaintext;
$artist = $row->find('td',1)->plaintext;
$title = $row->find('td',2)->plaintext;
$table[$artist][$title] = true;
}
echo '<pre>';
print_r($table);
echo '</pre>';
?>
We can see that this code can be (trivially) changed to reformat the data in any other way as well.
I tried simple_html_dom but on larger files and on repeat calls to the function I am getting zend_mm_heap_corrupted on php 5.3 (GAH). I have also tried preg_match_all (but this has been failing on a larger file (5000) lines of html, which was only about 400 rows of my HTML table.
I am using this and its working fast and not spitting errors.
$dom = new DOMDocument();
//load the html
$html = $dom->loadHTMLFile("htmltable.html");
//discard white space
$dom->preserveWhiteSpace = false;
//the table by its tag name
$tables = $dom->getElementsByTagName('table');
//get all rows from the table
$rows = $tables->item(0)->getElementsByTagName('tr');
// get each column by tag name
$cols = $rows->item(0)->getElementsByTagName('th');
$row_headers = NULL;
foreach ($cols as $node) {
//print $node->nodeValue."\n";
$row_headers[] = $node->nodeValue;
}
$table = array();
//get all rows from the table
$rows = $tables->item(0)->getElementsByTagName('tr');
foreach ($rows as $row)
{
// get each column by tag name
$cols = $row->getElementsByTagName('td');
$row = array();
$i=0;
foreach ($cols as $node) {
# code...
//print $node->nodeValue."\n";
if($row_headers==NULL)
$row[] = $node->nodeValue;
else
$row[$row_headers[$i]] = $node->nodeValue;
$i++;
}
$table[] = $row;
}
var_dump($table);
This code worked well for me.
Example of original code is here.
http://techgossipz.blogspot.co.nz/2010/02/how-to-parse-html-using-dom-with-php.html
I'm creating a "Madlibs" page where visitors can create funny story things online. The original files are in XML format with the blanks enclosed in XML tags
(Such as blablabla <PluralNoun></PluralNoun> blablabla <Verb></Verb> ).
The form data is created using XSL and the results are saved using a $_POST array. How do I post the $_POST array between the matching XML tags and then display the result to the page? I'm sure it uses a "foreach" statement, but I'm just not familiar enough with PHP to figure out what functions to use. Any help would be great.
Thanks,
E
I'm not sure if I understood your problem quite well, but I think this might help:
// mocking some $_POST variables
$_POST['Verb'] = 'spam';
$_POST['PluralNoun'] = 'eggs';
// original template with blanks (should be loaded from a valid XML file)
$xml = 'blablabla <PluralNoun></PluralNoun> blablabla <Verb></Verb>';
$valid_xml = '<?xml version="1.0"?><xml>' . $xml . '</xml>';
$doc = DOMDocument::loadXML($valid_xml, LIBXML_NOERROR);
if ($doc !== FALSE) {
$text = ''; // used to accumulate output while walking XML tree
foreach ($doc->documentElement->childNodes as $child) {
if ($child->nodeType == XML_TEXT_NODE) { // keep text nodes
$text .= $child->wholeText;
} else if (array_key_exists($child->tagName, $_POST)) {
// replace nodes whose tag matches a POST variable
$text .= $_POST[$child->tagName];
} else { // keep other nodes
$text .= $doc->saveXML($child);
}
}
echo $text . "\n";
} else {
echo "Failed to parse XML\n";
}
Here is PHP foreach syntax. Hope it helps
$arr = array('fruit1' => 'apple', 'fruit2' => 'orange');
foreach ($arr as $key => $val) {
echo "$key = $val\n";
}
and here is the code to loop thru your $_POST variables:
foreach ($_POST as $key => $val) {
echo "$key = $val\n";
// then you can fill each POST var to your XML
// maybe you want to use PHP str_replace function too
}
I have the following two errors when using XMLReader.
1) Warning: XMLReader::read() [xmlreader.read]: MyXML.xml:43102: parser error : xmlParseEntityRef: no name
2) Warning: XMLReader::read() [xmlreader.read]: ^ in MyXMLReader.php on line 56
Does anyone know what those refer to?
My PHP Code (The XML file is about 100MB so I can't include it):
<?php
//Assign file names
$XMLFile = 'MyXML.xml';
$CSVFile = 'MyCSV.csv';
//take start time to calculate run-time
$time_start = time();
//Open PHP's XMLReader. XMLReader opens each element in the XML one by one to keep memory use small.
$xml = new XMLReader();
$xml->open($XMLFile, null, 1<<19);
//Loop through all elements. Save all text from tags and attributes.
while ($xml->read()) {
if($xml->nodeType == XMLReader::TEXT) {
$row[$xml->name] = $xml->value;
}
if($xml->hasAttributes) {
while($xml->moveToNextAttribute()) {
$row[$xml->name] = $xml->value;
}
}
}
//save the titles which should appear in CSV file. All others will not be included.
$SavedRows = $row;
unset($row);
//Remove unnecessary columns i.e. datasource URLs
$RemoveColumn='xmlns:message, xmlns:common, xmlns:frb, xmlns:xsi, xsi:schemaLocation, xmlns:kf';
$RemoveColumns = explode(',', $RemoveColumn);
foreach($RemoveColumns as $key => $val) {
$val = trim($val);
unset($SavedRows[$val]);
}
//initiate all rows which should be included
foreach($SavedRows as $key => $val) {
$row[$key] = '';
}
//Create csv file
$fp = fopen($CSVFile, 'w');
//Input the column headings as first row
fputcsv($fp, array_keys($row), ',');
// Start 2nd loop through XML.
$xml = new XMLReader();
$xml->open($XMLFile, null, 1<<19);
while ($xml->read()) {
//Determine if tag is empty (An empty tag will contain data) Non empty tags contain series information.
$Output = $xml->isEmptyElement;
//Take data from non empty XML tags
if($xml->nodeType == XMLReader::TEXT) {
if(isset($SavedRows[$xml->name])) {
$row[$xml->name] = $xml->value;
}
}
//take data from XML tag attributes
if($xml->hasAttributes) {
while($xml->moveToNextAttribute()) {
if(isset($SavedRows[$xml->name])) {
$row[$xml->name] = $xml->value;
}
}
}
//If tag is empty, assume it is data and write row to file.
if($Output) {
fputcsv($fp, array_values($row), ',');
}
}
//Close file handle
fclose($fp);
//Calculate runtime
$time_end = time();
$time = $time_end - $time_start;
echo "Complete. Runtime: $time seconds";
?>
xmlParseEntityRef: no name
Means you've got bogus unescaped ampersands in the XML file. (Well, “XML”... technically if it ain't well-formed, it ain't XML.)
You'll need to check the file for lone &s (or fix the code that generated it) to escape them to &. According to the error, the first one's on line 43102 of the file (yikes!).