Displaying xml soap response to html table using PHP - php

I'm trying to display the xml soap response to HTMl table using PHP but I'm getting warning and data are not showing. Here is what I tried. Do you have any Idea what is wrong in my code? I'm new to XML. Thank you in advance.
XML Response:
Array ( [soap_Body] => Array ( [RunVRSCommandResult] => STOREREPORTFILE
MANGO00011005050APPLE00021006040MELON00031007030WATERMELON00041008020
CODE:
<body>
<table border="0" cellpadding="2" cellspacing="3" width="100%">
<tr>
<th>Fruits Name</th>
<th>Quantity</th>
<th>Sold</th>
<th>Remaining</th>
</tr>
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
XML
));
$response = curl_exec($curl);
curl_close($curl);
$plainXML = mungXML(trim($response));
$arrayResult = json_decode(json_encode(SimpleXML_Load_String($plainXML,
'SimpleXMLElement', LIBXML_NOCDATA)), true);
foreach ($arrayResult as $data) {
?>
<tr>
<td><?php echo $data->fruit_name; ?></td>
<td><?php echo $data->quantity; ?></td>
<td><?php echo $data->sold; ?></td>
<td><?php echo $data->remaining; ?></td>
</tr>`enter code here`
<?php
}
function mungXML($xml)
{
$obj = SimpleXML_Load_String($xml);
if ($obj === FALSE) return $xml;
$nss = $obj->getNamespaces(TRUE);
if (empty($nss)) return $xml;
$nsm = array_keys($nss);
foreach ($nsm as $key) {
$rgx
= '#'
. '('
. '\<'
. '/?'
. preg_quote($key)
. ')'
. '('
. ':{1}'
. ')'
. '#';
$rep
= '$1'
. '_';
$xml = preg_replace($rgx, $rep, $xml);
}
return $xml;
}
?>
OUTPUT:

Related

How to use simple html DOM for this table?

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.

xpath match not working

I'm trying to fetch the content of message field with "//td[text()='message']/following-sibling::*/text()" from this result ( from curl ):
<BODY bgcolor=#dddddd>
<TABLE bgcolor=#dddddd border=1>
<TR>
<TD valign="top"><B>Something</B></TD>
<TD>ca</TD>
</TR>
<TR>
<TD valign="top"><B>Some list</B></TD>
<TD>
<TABLE>
<TR>
<TD>CA</TD>
</TR>
</TABLE>
</TD>
</TR>
<TR>
<TD valign="top"><B>message</B></TD>
<TD>CA already existed.</TD>
</TR>
</TABLE>
</BODY>
<br>
But it doenst seens to work, The funny thing is using the same expression with python i can get it to work. So, how could i get the content of the message field?
PS: I'm using this online tester tool: http://www.xpathtester.com/test
EDIT: This is my actual php code:
<?php
function get_url_data($acl)
{
// curl request
$xml_content = http_request($acl);
echo $xml_content ;
$dom = new DOMDocument();
#$dom->loadXML($xml_content);
$xpath = new DomXPath($dom);
$content_title = $xpath->query("//td[text()='message']/following-sibling::*/text()");
return $content_title;
}
if(isset($_POST)==true && empty($_POST)==false){
//Convert content of text area into an array
$data = explode("\n", str_replace("\r", "", $_POST['sendme']));
}
foreach ($data as $name => $value){
$content = get_url_data($value);
foreach ($content as $value)
{
echo $value->nodeValue . "<br/>";
}
echo "<br>";
}
?>
I was able to get it working with:
<?php
if(isset($_POST)==true && empty($_POST)==false){
//Convert content of text area into an array
$data = explode("\n", str_replace("\r", "", $_POST['sendme']));
}
foreach ($data as $name => $value){
$content = create_acl($value);
$doc = new DOMDocument;
$doc->preserveWhiteSpace = false;
#$doc->loadHTML($content);
$xpath = new DOMXpath($doc);
$filtered = $xpath->query("//td[text()='message']/following-sibling::*/text()");
foreach ($filtered as $e) {
echo $e->nodeValue;
}
echo "<br>";
}
?>

input xml file to php with multiple elements in a element?

Hello i am having much trouble inputting the following XML because of the multiple "authors" .. it works when i try with 1 but with multiple it fails. does anyone know how i can do the multiple author input? below is my an example of the xml and code
<pub>
<ID>3</ID>
<title>A Sampling Based Approach to Facial Feature Extraction</title>
<year>2005</year>
<booktitle>AutoID</booktitle>
<pages>51-56</pages>
<authors>
<author>john johnson</author>
<author>billy bob</author>
</authors>
</pub>
my code:
<?php
$pubs = new SimpleXMLElement('p.xml', null, true);
echo <<<EOF
<table>
<tr>
<th>ID</th>
<th>title</th>
<th>year</th>
<th>booktitle</th>
<th>pages</th>
<th>authors</th>
</tr>
EOF;
foreach($pubs as $pub)
{
echo <<<EOF
<tr>
<td>{$pub->ID}</td>
<td>{$pub->title}</td>
<td>{$pub->year}</td>
<td>{$pub->booktitle}</td>
<td>{$pub->pages}</td>
<td>{$pub->authors}</td>
</tr>
EOF;
}
echo '</table>';
?>
The authors are a several nodes, so you have to use a second loop. Additionally if you output values in HTML/XML, you need to escape them. htmlspecialchars() does a good enough job for that.
You're transforming XML into HTML here. XSLT would be a better tool for that. It is supported by the XSL extension in PHP.
In PHP you can use Xpath to extract data from XML:
$dom = new DOMDocument();
$dom->load('p.xml');
$xpath = new DOMXpath($dom);
echo <<<EOF
<table>
<tr>
<th>ID</th>
<th>title</th>
<th>year</th>
<th>booktitle</th>
<th>pages</th>
<th>authors</th>
</tr>
EOF;
$pubs = $xpath->evaluate('//pub');
foreach($pubs as $pub) {
echo '<tr>', "\n";
echo '<td>', htmlspecialchars($xpath->evaluate('string(./ID)', $pub)), '</td>', "\n";
echo '<td>', htmlspecialchars($xpath->evaluate('string(./title)', $pub)), '</td>', "\n";
echo '<td>', htmlspecialchars($xpath->evaluate('string(./year)', $pub)), '</td>', "\n";
echo '<td>', htmlspecialchars($xpath->evaluate('string(./booktitle)', $pub)), '</td>', "\n";
echo '<td>', htmlspecialchars($xpath->evaluate('string(./pages)', $pub)), '</td>', "\n";
// fetch all the authors into an array
$authors = array();
foreach ($xpath->evaluate('./authors/author', $pub) as $author) {
$authors[] = $author->nodeValue;
}
echo '<td>'.htmlspecialchars(implode(', ', $authors)).'</td>', "\n";
echo '</tr>', "\n";
}
echo '</table>';
The example uses DOMXpath::evaluate() because it allows to query string directly from the DOM. $xpath->evaluate('string(./ID)', $pub) returns the text content inside the ID child of the context node $pub, or an empty string if here is no child element ID.
The simpliest way, i think, is to convert it to json string than back to array and you will see that is an array so you will need another foreach
$pubs = new SimpleXMLElement('p.xml', null, true);
$jsonString = json_encode($pubs);
$assocArray = json_decode($jsonString, true);
echo '<pre>';
var_dump($assocArray);
echo '</pre>';
Sorry. I give you wrong informations, because if you tried this code you will get different result if you have more than 1 '' tags and if you have only 1.
So i have another solution:
<?php
$pubs = new SimpleXMLElement('test.xml', null, true);
echo <<<EOF
<table>
<tr>
<th>ID</th>
<th>title</th>
<th>year</th>
<th>booktitle</th>
<th>pages</th>
<th>authors</th>
</tr>
EOF;
$pubsXpath = $pubs->xpath('//pub');
/** #var SimpleXMLElement $pub */
foreach ($pubsXpath as $pub) {
$authorsSxml = $pub->xpath('authors/author');
$authors = join(', ', $authorsSxml);
echo <<<EOF
<tr>
<td>{$pub->ID}</td>
<td>{$pub->title}</td>
<td>{$pub->year}</td>
<td>{$pub->booktitle}</td>
<td>{$pub->pages}</td>
<td>{$authors}</td>
</tr>
EOF;
}
echo '</table>';
?>

Wordpress plugin display query in linked file

I am creating a wordpress plugin that will query a db based off of user entered parameters and display the results in a linked html file. I can get it to display the html page, but the results variable is not passing through.
Here is how I am displaying the linked HTML file:
//This is set in another location but
$template = 'results';
//Execute SQL
global $wpdb;
$result = $wpdb->get_results($sql);
//Load template
$content = file_get_contents( plugins_url( 'template-files/'.$template.'.php',__FILE__ ) );
foreach ( $result as $r ){
$contentCopy = $content;
echo jww_display_php_file($contentCopy, $r);
}
function jww_display_php_file( $content, $r ){
$arr = (array)$r;
ob_start() && extract($arr, EXTR_SKIP);
eval('?>'.$content);
$content = ob_get_clean();
ob_flush();
$content .= "<hr>";
return $content;
}
Here is what I have in the HTML File:
<table width="100%" border="1" cellspacing="0" cellpadding="0">
<tr>
<td>Name</td>
<td><?php echo $Name; ?></td>
</tr>
</table>
Thanks in advance for any help
First of all, your results.html should be results.php, you just can't use php variables or functions inside an HTML file, so rename your file to results.php and then try this
$result = $wpdb->get_results($sql);
$content = file_get_contents( plugins_url( 'template-files/results.php',__FILE__ ) );
foreach ( $result as $r ){
$contentCopy = $content;
echo jww_display_file($contentCopy, $r);
}
function jww_display_file( $content, $r ){
$arr = (array)$r;
ob_start() && extract($arr, EXTR_SKIP);
eval('?>'.$content);
$content = ob_get_clean();
ob_flush();
$content .= "<hr>";
return $content;
}
Finally, inside your results.php file, change following
<td><?php echo $r->Name; ?></td>
<td><?php echo $r->Age; ?></td>
<td><?php echo $r->DOB; ?></td>
to
<td><?php echo $Name; ?></td>
<td><?php echo $Age; ?></td>
<td><?php echo $DOB; ?></td>
Note : eval is evil but it's not a problem when you are using an internal file from your server and you know the code is secure, this way, framework like Laravel loads a view file and mix variables from controller in their MVC framework.
I renamed my results.php to results.html, changed the $content = file_get_contents( plugins_url( 'template-files/'.$template.'.html',FILE ) ); and it works perfectly!

Undefined offset issue in explode

Firstly I apologise for asking a question which must be somewhat rookie or simple, but I cannot seem to find any code that I've researched to solve my problem.
Notice: Undefined offset: 1 in C:\Users\Joshua\Desktop\USBWebserver v8.5\8.5\root\Assignment\Table.php on line 14
This error continues from Offset 1 - 7.
The code that I am currently using to pull the data from the CSV file is as follows:
<?php
$fp = fopen ("quotes.csv","r");
if (!$fp) {echo "<p>Unable to open remote file.</p>"; exit;}
?>
<table>
<tr><th>ID</th> <th>Price</th> <th>Volume </th></tr>
<?php
$i=0;
while (!feof($fp)):
$line = fgets($fp, 2048);
$out[$i] = array($line);
list ($ID, $Price, $StockDate, $StockTime, $Change, $DayHI, $DayLOW, $Volume,) = explode(",", $out[$i][0]);
echo "<tr><td>$ID</td> <td>$Price</td> <td>$StockDate </td><td>$StockTime</td> <td>$Change</td> <td>$DayHI</td> <td>$DayLOW</td> <td>$Volume</td></tr>";
$fp++;
$i++;
endwhile;
?>
</table>
<?php
//echo "<p>".$out[0][0]."</p>";
//echo "<p>".$out[1][0]."</p>";
//echo "<p>".$out[2][0]."</p>";
fclose($fp);
?>
I'm unsure as to how something is undefined as the correct number of values are being called from the CSV.
I understand this isn't a site to teach someone PHP basics but any advice would be appreciated to help solve the problem, I would be appreciative!
I think you didn't want to +1 on file pointer:
$fp++;
Removing this line should do the trick.
UPDATE:
You should also check fgets if it's not false, because it means end of file:
$line = fgets($fp, 2048);
if($line === false) break;
Fully working example:
<?php
$fp = fopen ("quotes.csv","r");
if (!$fp) {echo "<p>Unable to open remote file.</p>"; exit;}
?>
<table>
<tr><th>ID</th> <th>Price</th> <th>Volume </th></tr>
<?php
$out = array();
$i=0;
while (!feof($fp)):
$line = fgets($fp, 2048);
if($line === false) break;
$out[$i] = array($line);
list ($ID, $Price, $StockDate, $StockTime, $Change, $DayHI, $DayLOW, $Volume) = explode(",", $out[$i][0]);
echo "<tr><td>$ID</td> <td>$Price</td> <td>$StockDate </td><td>$StockTime</td> <td>$Change</td> <td>$DayHI</td> <td>$DayLOW</td> <td>$Volume</td></tr>";
$i++;
endwhile;
?>
</table>
<?php
echo "<p>".$out[0][0]."</p>";
fclose($fp);
Last echo gave me my first string line from .csv.
Try making a single variable for the exploded values and check if the variable contains all the data
$temporal_var = explode(",", $out[$i][0]);
print_r($temporal_var);
Do you have initialized the $out array? moreover for what i see you don't need the $i index since you can just call $out[] = array($line); to append an element to the array
Try this approach, using the native php CSV handler:
<?php
// Set a list of headers
$ths[0] = 'ID';
$ths[1] = 'Price';
$ths[2] = 'StockDate';
$ths[3] = 'StockTime';
$ths[4] = 'Change';
$ths[5] = 'DayHI';
$ths[6] = 'DayLOW';
$ths[7] = 'Volume';
// Open the file with error handling
$fp = fopen('quotes.csv', 'r');
if( !$fp ) { die('<p>Unable to open remote file.</p>'); }
// Get the size
$fz = filesize('quotes.csv') + 1;
// Create a Data holder array
$fpData = array();
// While there is a line. Use native fgetcsv()
while ( $fpRow = fgetcsv( $fp, $fz, ',' ) ) {
// For each element in the row we asign it to its header
for ($i=0; $i < count($fpRow); $i++) {
$thisRow[ $ths[$i] ] = $fpRow[ $i ];
}
// Append to the Data array
$fpData[] = $thisRow;
}
// Close the file
fclose($fp);
// Test the output
// print_r( $fpData );
?>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Get CVS</title>
</head>
<body>
<table>
<thead>
<tr>
<?php foreach ($ths as $thisField): ?>
<th><?php echo $thisField ?></th>
<?php endforeach ?>
</tr>
</thead>
<tbody>
<?php foreach ($fpData as $thisItem): ?>
<tr>
<td><?php echo $thisItem['ID'] ?></td>
<td><?php echo $thisItem['Price'] ?></td>
<td><?php echo $thisItem['StockDate'] ?></td>
<td><?php echo $thisItem['StockTime'] ?></td>
<td><?php echo $thisItem['Change'] ?></td>
<td><?php echo $thisItem['DayHI'] ?></td>
<td><?php echo $thisItem['DayLOW'] ?></td>
<td><?php echo $thisItem['Volume'] ?></td>
</tr>
<?php endforeach ?>
</tbody>
</table>
</body>
</html>

Categories