I'm tring to process xml (website) into php array.
I have tried the following code which works for everyting in results but i need to get the totalpage which i'm not able to see how I can do this.
function get_content($url)
/// basically opens the page and stores it as a variable. Buggered if I know how it works!
{
$ch = curl_init();
curl_setopt ($ch, CURLOPT_URL, $url);
curl_setopt ($ch, CURLOPT_HEADER, 0);
ob_start();
curl_exec ($ch);
curl_close ($ch);
$string = ob_get_contents();
ob_end_clean();
return $string;
$string = NULL;
$ch = NULL;
$url = NULL;
}
$url = "url";
$content = get_content($url);
$content_x = explode("<result>", $content);
foreach ($content_x as $item)
{
$p1 = strpos($item, '<title>');
$p2 = strpos($item, '</title>');
$l1 = $p2 - $p1;
echo '<br>'.$title = substr($item, $p1, $l1);
}
xml site feed
<?xml version="1.0" encoding="UTF-8"?>
<response version="2">
<totalpage>1005</totalpage>
<results>
<result>
<title>test</title>
<title2>test2</title2>
<title3>test3</title3>
<result>
<result>
<title>test</title>
<title2>test2</title2>
<title3>test3</title3>
<result>
<result>
<title>test</title>
<title2>test2</title2>
<title3>test3</title3>
<result>
........so on
<results>
</response>
I need to get totalpage and everyting in results
How do get totalpage and is they better way to process the results
You absolutely should not be using string manipulation to try to parse XML. There are any number of PHP libraries that can do this. I might recommend SimpleXML.
Usage would be:
$xml = simplexml_load_string($content);
$totalpage = $xml->response->totalpage;
Related
My XML to be parsed is in this format:
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope">
<env:Header />
<env:Body>
<n0:ZFM_PAYSLIP1Response xmlns:n0="urn:sap-com:document:sap:rfc:functions">
<LS_EMP_PAYSLIP_DATA>
<ZEMP_NO>00199999</ZEMP_NO>
<ZEMP_NAME>AJ KUMAR</ZEMP_NAME>
<ZSAL_MONTH>JUL-2016</ZSAL_MONTH>
<ZBASIC_PAY>57240.0</ZBASIC_PAY>
<ZGROSS_PAY>145062.29</ZGROSS_PAY>
<ZNET_PAY>50728.0</ZNET_PAY>
<ZINCOME_TAX>25858.0</ZINCOME_TAX>
<ZLEAVE_ENCASH>0.0</ZLEAVE_ENCASH>
<ZDUTY_PAY>41976.0</ZDUTY_PAY>
<ZDA>56950.4</ZDA>
<ZPERKS>26330.4</ZPERKS>
<ZHRA>11448.0</ZHRA>
<ZTOT_DEDUCTIONS>94334.29</ZTOT_DEDUCTIONS>
<ZCPF>12787.0</ZCPF>
<ZVPF>50000.0</ZVPF>
<ZLIC>0.0</ZLIC>
<ZTHRIFT_FUND>0.0</ZTHRIFT_FUND>
<ZGRP_INS>160.0</ZGRP_INS>
<ZPROF_TAX>200.0</ZPROF_TAX>
<ZDUTY_DAYS>18</ZDUTY_DAYS>
<ZWEEK_OFF>4</ZWEEK_OFF>
<ZFL />
<ZCL />
<ZEL />
<ZFPL />
<ZHPL>8</ZHPL>
<ZCML />
<ZEOL />
<ZUAB />
<ZDEISGNATION>Sr.Manager(IT)</ZDEISGNATION>
<ZDEPT_CODE>03007900</ZDEPT_CODE>
<ZCL_BAL>3</ZCL_BAL>
<ZEL_BAL>270.5</ZEL_BAL>
<ZHPL_BAL>180</ZHPL_BAL>
</LS_EMP_PAYSLIP_DATA>
</n0:ZFM_PAYSLIP1Response>
</env:Body> </env:Envelope>
I am using PHP curl to get data from remote with
this PHP code :
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,'http://hostanme.tld/ERP_PAY_XML.xml');
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
//echo $result;
curl_close($ch);
$xml = simplexml_load_string($result);
$ns = $xml->getNamespaces(true);
$soap = $xml->children($ns['env']);
echo "<br> len-soap : " . $soap;
$getaddressresponse = $soap->Body->children($ns['n0']);
foreach ($getaddressresponse->getLocationForGroupResponse->children($ns['n0']) as $item)
{
$item = $item->children();
echo $item->address . '<br />';
}
?>
but still I am not getting any result. Anybody please help..
Is there any other way to parse XML to an object..
I want to extract url data just like as facebook. For that I am using php DOMDocument.While retrieving the DOM content i.e while retrieving "title" the DOMDocument is returning 0 elements. Here is my code
<?php
header("Content-Type: text/xml");
echo '<?xml version="1.0" encoding="UTF-8" ?>';
//$url = $_REQUEST["url"];
$url = "http://business.tutsplus.com/articles/how-to-set-up-your-first-magento-store--fsw-43137";
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_HEADER,0);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch,CURLOPT_FOLLOWLOCATION,1);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
$data = curl_exec($ch);
curl_close($ch);
$dom = new DOMDocument();
#$dom->loadHTML($data);
$title = $dom->getElementsByTagName("title");
//$title = $dom->find("title");
echo "<urlData>";
echo "<title>";
echo $title->length;
echo "</title>";
echo "</urlData>";
?>
Here $title->length is returning 0 elements. What is the problem?
How to remove all nodes like xml:space="preserve" from XML, to get clean result
old XML
<table>
<actor xml:space="preserve"> </actor>
</table>
I want result be like this
<table>
<actor> </actor>
</table>
EDIT
this the php code
function produce_XML_object_tree($raw_XML) {
libxml_use_internal_errors(true);
try {
$xmlTree = new SimpleXMLElement($raw_XML);
} catch (Exception $e) {
// Something went wrong.
$error_message = 'SimpleXMLElement threw an exception.';
foreach(libxml_get_errors() as $error_line) {
$error_message .= "\t" . $error_line->message;
}
trigger_error($error_message);
return false;
}
return $xmlTree;
}
$xml_feed_url = "www.xmlpage.com/web.xml";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $xml_feed_url);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$xml = curl_exec($ch);
curl_close($ch);
$cont = produce_XML_object_tree($xml);
echo json_encode($cont);
Use an xpath expression to locate the attributes and remove them.
Example:
//$xml = your xml string
$dom = new DOMDocument();
$dom->loadXML($xml);
$xpath = new DOMXPath($dom);
foreach ($xpath->query('//#xml:space') as $attr) {
$attr->ownerElement->removeAttributeNode($attr);
}
echo $dom->saveXML();
Output:
<?xml version="1.0"?>
<table>
<actor> </actor>
</table>
This will remove any xml:space attributes. If you want to target only those xml:space attributes that have a value of "preserve", change the query to //#xml:space[.="preserve"].
$string = str_ireplace('xml:space="preserve"','',$string);
function produce_XML_object_tree($raw_XML) {
libxml_use_internal_errors(true);
try {
$xmlTree = new SimpleXMLElement($raw_XML);
} catch (Exception $e) {
// Something went wrong.
$error_message = 'SimpleXMLElement threw an exception.';
foreach(libxml_get_errors() as $error_line) {
$error_message .= "\t" . $error_line->message;
}
trigger_error($error_message);
return false;
}
return str_ireplace('xml:space="preserve"','',$xmlTree;);
}
$xml_feed_url = "www.xmlpage.com/web.xml";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $xml_feed_url);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$xml = curl_exec($ch);
curl_close($ch);
$cont = produce_XML_object_tree($xml);
echo json_encode($cont);
As long as you're concerned to remove all attribute-nodes that are with a namespace prefix, you can do so by selecting them via xpath and remove them from the XML document.
The xpath query for all attributes with a prefix can be obtained by comparing the name (that is prefix and local-name) with the local-name (that is the local-name only). If it differs you've got a match:
//#*[name(.) != local-name(.)]
Querying specific nodes with SimpleXML and XPath to delete them has been outlined earlier as an answer to the question Remove a child with a specific attribute, in SimpleXML for PHP (Nov 2008) and is pretty straight-forward by using the SimpleXML-Self-Reference:
$xml = simplexml_load_string($buffer);
foreach ($xml->xpath('//#*[name(.) != local-name(.)]') as $attr) {
unset($attr[0]);
}
The self-reference here is to remove the attribute $attr via $attr[0].
Full Example:
$buffer = <<<XML
<table>
<actor class="foo" xml:space="preserve"> </actor>
</table>
XML;
$xml = simplexml_load_string($buffer);
foreach ($xml->xpath('//#*[name(.) != local-name(.)]') as $attr) {
unset($attr[0]);
}
echo $xml->asXML();
Example Output:
<?xml version="1.0"?>
<table>
<actor class="foo"> </actor>
</table>
I m accessing an api and reading the content with Simplexml element.But when i m using foreach loop for accessing the values for nodes.It gives me value for only first loop.not for others....
below is my code
<?php
include('connection.php');
header("Content-Type: text/xml;");
function httpGet($url)
{
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
// curl_setopt($ch,CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'header1:value1',
'header2:value2'
));
$output=curl_exec($ch);
curl_close($ch);
return $output;
}
$data= httpGet("http://apiurl");
$xml = new SimpleXMLElement($data);
foreach ($xml->node1->node2->node3 as $info) {
echo $info->name, ' played by ', $info->actor, PHP_EOL;
}
?>
xml format which i m reading
<?xml version='1.0' standalone='yes'?>
<main>
<node1>
<title>PHP: Behind the Parser</title>
<node2>
<node3>
<name>Ms. Coder</name>
<actor>Onlivia Actora</actor>
</node3>
</node2>
<node2>
<node3>
<name>Mr. Coder</name>
<actor>El ActÓr</actor>
</node3>
</node2>
</node1>
</main>
When i m running above php code for reading api content which is having xml format as shown above.
I want to read name and actor node using foreach loop.but i m not able to access only first name and actor node under node3,not the second one....
Please correct the foreach loop or any flaw in code..Please highlight and help me in correcting that....
maybe set it like this
foreach ($xml->node1->node2 as $info) {
echo $info->node3->name, ' played by ', $info->node3->actor, PHP_EOL;
}
I've recently changed my web hosting and unfortunately the administrator has disabled file_get_content and some other functions.
The aim of this script is to get iOS device's information directly from device. Before, I was using this code to do so:
$content = file_get_contents('php://input');
file_put_contents("data.txt", $content);
And the result was like this (in data.txt)
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IMEI</key>
<string>01 257233 621346 0</string>
<key>PRODUCT</key>
<string>iPhone2,1</string>
<key>SERIAL</key>
<string>5K1124GHEDG</string>
<key>UDID</key>
<string>07cc825055gftr4edsa3f06d0373376a7664a66a</string>
<key>VERSION</key>
<string>10B329</string>
</dict>
</plist>
As the Curl function is enabled on my server, I tried this code in some different ways, but didn't work. The data.txt is emptied as a result!
$ch = curl_init();
$timeout = 0;
curl_setopt ($ch, CURLOPT_URL, "php://input");
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
$contents = curl_exec($ch);
curl_close($ch);
file_put_contents("data.txt", $contents);
UPDATED:
Let me explain how it works. We direct users to a profile which is stored on our server(e.g device.mobileconfig). Once users click on that, they will be asked to install that. Its content is:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PayloadContent</key>
<dict>
<key>URL</key>
<string>http://mywebsite.com/get.php</string>
<key>DeviceAttributes</key>
<array>
<string>UDID</string>
<string>VERSION</string>
<string>PRODUCT</string>
<string>SERIAL</string>
</array>
</dict>
<key>PayloadDescription</key>
<string>Install to get device info</string>
<key>PayloadDisplayName</key>
<string>UDID Finder</string>
<key>PayloadIdentifier</key>
<string>com.myud.ir</string>
<key>PayloadOrganization</key>
<string>MyUD.ir</string>
<key>PayloadRemovalDisallowed</key>
<false/>
<key>PayloadType</key>
<string>Profile Service</string>
<key>PayloadUUID</key>
<string>57A223FD-F675-90B1-8F43-22D3FC3BC181</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</plist>
The profile runs get.php to fetch data from device. I tried Cristian's one but did not work. I probably have a mistake some where. The get.php is:
<?php
$xml = new SimpleXMLElement('<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist version="1.0"/>');
$dict = $xml->addChild('dict');
foreach ($_POST as $item => $value) {
$dict->addChild('string', $item);
$dict->addChild('key', $value);
}
file_put_contents("data.txt", trim(str_replace('<?xml version="1.0"?>', '', $xml->asXML())));
?>
P.S.
I just need the data between
<dict></dict>
Assuming that php://input is a read-only stream that allows you to read raw data from the request body, you can solve this problem by fetching $_POST data then create an xml document using php's SimpleXMLElement class witch then will be written to data.txt.
You can proceed in this way:
$xml = new SimpleXMLElement('<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist version="1.0"/>');
$dict = $xml->addChild('dict');
foreach ($_POST as $item => $value) {
$dict->addChild('string', $item);
$dict->addChild('key', $value);
}
file_put_contents("data.txt", trim(str_replace('<?xml version="1.0"?>', '', $xml->asXML())));
Another solution:
$f = fopen('php://input','r');
$out = fopen('data.txt','w');
$body = "";
while( $line = fgets( $f ) ) {
$body .= $line;
}
fwrite($out, $body);
fclose($f);
fclose($out);
Thank you very much Cristian. it worked.
I also found another way which is PEAR php Component that provides lots of functions which are alternative to main php functions for those people who are struggling like me!
for instance, in my case, I uploaded the file_get_content function to the same folder and included that in get.php
instead of
$content = file_get_contents('php://input');
file_put_contents("data.txt", $content);
I'm now using
require_once 'file_get_contents.php';
$content = php_compat_file_get_contents('php://input');
file_put_contents("data.txt", $content);