I'm struggling to parse an XML file in PHP:
Here's the XML
<rss xmlns:ac="http://palm.com/app.catalog.rss.extensions" version="2.0">
<channel>
<title>Device App Updates for US</title>
<link>http://www.palm.com</link>
<description>Updates</description>
<language>en-US</language>
<pubDate>Mon, 04 Jan 2010 18:23:51 -0800</pubDate>
<lastBuildDate>Mon, 04 Jan 2010 18:23:51 -0800</lastBuildDate>
<ac:distributionChannel>Device</ac:distributionChannel>
<ac:countryCode>US</ac:countryCode>
<item>
<title><![CDATA[My App]]></title>
<link>http://developer.palm.com/appredirect/?packageid=com.palm.myapp</link>
<description><![CDATA[My fun app.]]></description>
<pubDate>2009-12-21 21:00:58</pubDate>
<guid>334.232</guid>
<ac:total_downloads>1234</ac:total_downloads>
<ac:total_comments>12</ac:total_comments>
<ac:country>US</ac:country>
</item>
</channel>
</rss>
My Problem is; when I use:
$strURL = "http://developer.palm.com/rss/D/appcatalog.update.rss.xml";
$ch = curl_init($strURL);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, 0);
$data = curl_exec($ch);
curl_close($ch);
$doc = new SimpleXmlElement($data, LIBXML_NOCDATA);
print_r($doc);
I'm not able to display the values? The one I'm most interested in is <ac:total_downloads>1000</ac> but I don't seem to be able to parse it.
What am I doing wrong?
Many thanks
You don't need to use curl to retrieve that file, SimpleXML can fetch external resources.
Use children() to access namespaced nodes. Here's how to do it:
$rss = simplexml_load_file($strURL);
$ns = 'http://palm.com/app.catalog.rss.extensions';
foreach ($rss->channel->item as $item)
{
echo 'Title: ', $item->title, "\n";
echo 'Downloads: ', $item->children($ns)->total_downloads, "\n\n";
}
Related
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;
}
Following is my XML file i want to update the doller and cent values which are inside latestBid. I first tried the doller values but it's not working. i even tried to update the description ('//item[id="4"]/description') even that didn't work. Please tell me what i'm doing wrong here.
XML file
<?xml version="1.0"?>
<items>
<item>
<itemNumber>4</itemNumber>
<latestBid>
<latestCustomerId>1</latestCustomerId>
<bidPrice>
<doller>2342</doller>
<cent>23</cent>
</bidPrice>
</latestBid>
</item>
<item>
<itemNumber>5</itemNumber>
<latestBid>
<latestCustomerId>1</latestCustomerId>
<bidPrice>
<doller>35345</doller>
<cent>78</cent>
</bidPrice>
</latestBid>
</item>
</items>
PHP file
<?php
$url = '../../data/auction2.xml';
$itemNumber ="4";
$bidDoller = 45;
$bidCent=55;
$doc = new DomDocument();
$xml=simplexml_load_file($url);
//echo "came 1";working
foreach ($xml->xpath('//item[#itemNumber="4"]/latestBid/bidPrice/doller') as $desc) {
echo "came 2";//nt working
$dom=dom_import_simplexml($desc);
$dom->nodeValue = $bidDoller;
}
file_put_contents($url, $xml->asXML());
?>
edited. Still not working
thank you every one for the support by editing and answering I finally did it. since it wasn't easy for me to do this i'm posting the answer to help someone like me :).
i didn't change the xml.
php file
$url = '../../data/auction2.xml';
$itemNumber ="4";
$bidDoller = 85;
$bidCent=95;
$xml=simplexml_load_file($url);
$resultDoller= $xml->xpath('//item[itemNumber="'.$itemNumber.'"]/latestBid/bidPrice/doller');
$resultCent= $xml->xpath('//item[itemNumber="'.$itemNumber.'"]/latestBid/bidPrice/cent');
$resultDoller[0][0]=$bidDoller;
$resultCent[0][0]=$bidCent;
print $xml->asXML();
file_put_contents($url, $xml->asXML());
Following worked for me,
//XML
<?xml version="1.0"?>
<items>
<item id="4">
<itemNumber>4</itemNumber>
<latestBid>
<latestCustomerId>1</latestCustomerId>
<bidPrice>
<doller>2342</doller>
<cent>23</cent>
</bidPrice>
</latestBid>
</item>
<item>
<itemNumber>5</itemNumber>
<latestBid>
<latestCustomerId>1</latestCustomerId>
<bidPrice>
<doller>35345</doller>
<cent>78</cent>
</bidPrice>
</latestBid>
</item>
</items>
//PHP
<?php
$url = '../../data/auction2.xml';
$itemNumber ="4";
$bidDoller = 45;
$bidCent=55;
$doc = new DomDocument();
$xml=simplexml_load_file($url);
$result = $xml->xpath('//item[#id="4"]/latestBid/bidPrice/doller');
echo "<pre>";
print_r($result);
//echo "came 1";working
foreach ($xml->xpath('//item[#id="4"]/latestBid') as $desc) {
echo "came 2";//nt working
$dom=dom_import_simplexml($desc);
$dom->nodeValue = $bidDoller;
}
//file_put_contents($url, $xml->asXML());
?>
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;
I have to parse an xml file that contains various namespaces.
I have already registered the namespaces.
My problem is that I cannot extract the data from the cal:location block.
For example i need the vcard:street-address or the vcard:postal-code.
XML - Example:
<channel>
<title>Veranstaltungen zum Thema Markt+Bauer vom 05.05.2011 bis 05.05.2012</title>
<link>https://www.wien.gv.at/vadb/internet/AdvPrSrv.asp?Layout=VAErgebnis_neu&Type=S&ganzjaehrig=ja</link>
<description> Veranstaltungen zum Thema Markt+Bauer vom 05.05.2011 bis 05.05.2012 </description>
<lastBuildDate>Sa,05 Jän 2013 17:38:05 GMT</lastBuildDate>
<ManagingEditor>event#ma55.wien.gv.at</ManagingEditor>
<language>de-AT</language>
<dc:license>http://data.wien.gv.at/nutzungsbedingungen</dc:license>
<dc:rightsHolder>Stadt Wien</dc:rightsHolder>
<item>
<title>Bauernmarkt am Karmelitermarkt</title>
<link>https://www.wien.gv.at/vadb/internet/AdvPrSrv.asp?Layout=VAErgebnis_neu&Type=K&ID=256811&return=</link>
<guid isPermaLink="false">https://www.wien.gv.at/vadb/internet/AdvPrSrv.asp?Layout=VAErgebnis_neu&Type=K&ID=256811&return=</guid>
<description><![CDATA[
<p>07.01.2011 bis 31.12.2011<br />
08:00 bis 13:00<br />
Karmelitermarkt<br />http://www.wiener-maerkte.at</p><p>Spezieller Bauernmarkt mit köstlichen naturreinen Produkten.</p>]]>
</description>
<category>Kulinarischer Markt</category>
<dc:subject>Kulinarischer Markt</dc:subject>
<cal:dtstart>2011-01-07T00:00:00+01:00</cal:dtstart>
<cal:dtend>2011-12-31T00:00:00+01:00</cal:dtend>
<cal:byday>Fr, Sa</cal:byday>
<cal:byhour>08</cal:byhour>
<cal:byminute>00</cal:byminute>
<cal:location>
<vcard:fn>Karmelitermarkt</vcard:fn>
<vcard:street-address>Haidgasse 1</vcard:street-address>
<vcard:postal-code>1020</vcard:postal-code>
<vcard:tel/>
<vcard:fax/>
<vcard:email>office#wiener-maerkte.at</vcard:email>
<vcard:url>http://www.wiener-maerkte.at</vcard:url>
</cal:location>
<cal:organizer>
<vcard:fn>Wiener Einkaufsstraßen-Management</vcard:fn>
<vcard:street-address>Hietzinger Kai 133</vcard:street-address>
<vcard:postal-code>1130</vcard:postal-code>
<vcard:tel>0043-1/514 50-6700</vcard:tel>
<vcard:fax>0043-1/514 50-6749</vcard:fax>
<vcard:email/>
<vcard:url>http://www.einkaufsstrassen.at</vcard:url>
</cal:organizer>
</item>
</channel>
My PHP - Code:
<?php
function download_feed($path){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$path);
curl_setopt($ch, CURLOPT_FAILONERROR,1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_TIMEOUT,15);
$retValue = curl_exec($ch);
curl_close($ch);
return $retValue;
}
$sXML = download_feed('xml - Example');
$oXML = new SimpleXMLElement($sXML);
foreach($oXML->channel->item as $oDocument){
$title = $oDocument->title;
$url = $oDocument->link;
$namespaces = $oDocument->getNameSpaces(true);
$cal = $oDocument->children($namespaces['cal']);
$vcard = $cal->children($namespaces['vcard']);
$dc = $oDocument->children($namespaces['dc']);
$georss = $oDocument->children($namespaces['georss']);
$byday = $cal->byday;
//var_dump($vcard);
$attrs = $oDocument->getElementsByTagName("vcard:fn");
$streetAddress = $oDocument->{'cal:location'}->{'vcard:fn'};
echo $title . "<br>" . $url . "<br>" . $byday. "<br>" . $streetAddress. "<br><br>";
}
?>
You've misunderstood the purpose of the ->children() method: it doesn't "register" namespaces, it selects them for immediate use.
So to get to <cal:location>, you can use $oDocument->children($namespaces['cal'])->location, and the <vcard:fn> inside that would be $oDocument->children($namespaces['cal'])->location->children($namespaces['vcard'])->fn
Since PHP 5.2, you can also use prefixes directly, rather than looking up their URLs, by giving the ->children() method an extra parameter of true: $oDocument->children('cal', true)->location->children('vcard', true)->fn
Trying to parse out lat/lon from a google maps rss feed:
$file = "http://maps.google.com/maps/ms?ie=UTF8&hl=en&vps=1&jsv=327b&msa=0&output=georss&msid=217909142388190116501.000473ca1b7eb5750ebfe";
$xml = simplexml_load_file($file);
$loc = $xml->channel->item;
echo $loc[0]->title;
echo $loc[0]->point;
The title shows up alright, but point gives me nothing. Each node looks like this:
<item>
<guid isPermaLink="false">0004740950fd067393eb4</guid>
<pubDate>Sun, 20 Sep 2009 21:47:49 +0000</pubDate>
<title>Big Wong King Restaurant</title>
<description><![CDATA[<div dir="ltr">$4.99 full meals!</div>]]></description>
<author>neufuture</author>
<georss:point>
40.716236 -73.998413
</georss:point>
<georss:elev>0.000000</georss:elev>
</item>
<?php
$file = "http://maps.google.com/maps/ms?ie=UTF8&hl=en&vps=1&jsv=327b&msa=0&output=georss&msid=217909142388190116501.000473ca1b7eb5750ebfe";
$xml = simplexml_load_file($file);
$loc = $xml->channel->item;
foreach ($loc->children('http://www.georss.org/georss') as $geo) {
echo $geo;
}
?>