Reputation: 1493
I am using yahoo weather api and i want to get the forecast details but the XML is showing two nodes like this
<yweather:forecast day="Thu" date="23 May 2013" low="32"
high="44" text="Clear" code="31"/>
<yweather:forecast day="Fri" date="24 May 2013" low="31"
high="44" text="Sunny" code="32"/>
Now how i can select the 2nd one please help for getting the node i am using this code and i am getting the first node values only.
$myxml=new SimpleXMLElement("http://weather.yahooapis.com/forecastrss?w=$woeid[0]&u=c",NULL,TRUE);
$ab=$myxml->children();
$ad=$ab->channel->item->children('yweather',true)->forecast->attributes();
$fhigh=(string) $ad->high;
$flow=(string) $ad->low;
$ftemptype=(string) $ad->text;
$fdate=(string) $ad->date;
I am getting $flow as 32 and $fdate as 23 May 2013
Upvotes: 1
Views: 1237
Reputation: 197787
If the next node means the next node with the same name as the current node and you access them via the parent node like in your case:
$ad = $ab->channel->item->children('yweather',true)->forecast->attributes();
Then the element-named ->forecast->
returns the first node of the same-named-element-children-simplexml-container. This can be also written as ->forecast[0]->
. The second element therefore is ->forecast[1]->
. Yes, that simple. Even this looks like an array, it's not one, but it works quite similar to one. So 0 is first element, 1 is second and so on:
$url = "http://weather.yahooapis.com/forecastrss?w=$woeid[0]&u=c";
$xml = simplexml_load_file($url);
$items = $xml->channel->item;
$forecasts = $items[0]->children('yweather', true)->forecast;
print_r($forecasts[0]->attributes()); # Day 1
print_r($forecasts[1]->attributes()); # Day 2
As you can see in this example, I use the numeric indexes at quite some places. That makes the code even a little more saying.
The second tip I give is that you use better named variable names. They will help you a lot to not loose sight. And you can waste variables in PHP, PHP is very good with them, so use them a lot.
Hope this helps.
Upvotes: 0
Reputation: 5114
Here's a simple solution using SimpleXML and Xpath. Just replace the $myxml
variable in my example with yours and it should be good to go:
<?php
$xml = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" version="2.0">
<channel>
<title>Yahoo! Weather - Sunnyvale, CA</title>
<link>http://us.rd.yahoo.com/dailynews/rss/weather/Sunnyvale__CA/*http://weather.yahoo.com/forecast/USCA1116_c.html</link>
<description>Yahoo! Weather for Sunnyvale, CA</description>
<language>en-us</language>
<lastBuildDate>Thu, 23 May 2013 12:55 pm PDT</lastBuildDate>
<ttl>60</ttl>
<yweather:location city="Sunnyvale" region="CA" country="United States" />
<yweather:units temperature="C" distance="km" pressure="mb" speed="km/h" />
<yweather:wind chill="17" direction="360" speed="22.53" />
<yweather:atmosphere humidity="48" visibility="16.09" pressure="1016.6" rising="0" />
<yweather:astronomy sunrise="5:53 am" sunset="8:14 pm" />
<image>
<title>Yahoo! Weather</title>
<width>142</width>
<height>18</height>
<link>http://weather.yahoo.com</link>
<url>http://l.yimg.com/a/i/brand/purplelogo//uh/us/news-wea.gif</url>
</image>
<item>
<title>Conditions for Sunnyvale, CA at 12:55 pm PDT</title>
<geo:lat>37.37</geo:lat>
<geo:long>-122.04</geo:long>
<link>http://us.rd.yahoo.com/dailynews/rss/weather/Sunnyvale__CA/*http://weather.yahoo.com/forecast/USCA1116_c.html</link>
<pubDate>Thu, 23 May 2013 12:55 pm PDT</pubDate>
<yweather:condition text="Fair" code="34" temp="17" date="Thu, 23 May 2013 12:55 pm PDT" />
<description><![CDATA[<img src="http://l.yimg.com/a/i/us/we/52/34.gif"/><br />
<b>Current Conditions:</b><br />
Fair, 17 C<BR />
<BR /><b>Forecast:</b><BR />
Thu - Sunny. High: 19 Low: 9<br />
Fri - Sunny. High: 21 Low: 11<br />
<br />
<a href="http://us.rd.yahoo.com/dailynews/rss/weather/Sunnyvale__CA/*http://weather.yahoo.com/forecast/USCA1116_c.html">Full Forecast at Yahoo! Weather</a><BR/><BR/>
(provided by <a href="http://www.weather.com" >The Weather Channel</a>)<br/>]]> </description>
<yweather:forecast day="Thu" date="23 May 2013" low="9" high="19" text="Sunny" code="32" />
<yweather:forecast day="Fri" date="24 May 2013" low="11" high="21" text="Sunny" code="32" />
<guid isPermaLink="false">USCA1116_2013_05_24_7_00_PDT</guid>
</item>
</channel>
</rss>
XML;
$myxml = new SimpleXMLElement($xml);
$myxml->registerXPathNamespace('yweather', 'http://xml.weather.yahoo.com/ns/rss/1.0');
$secondForecast = $myxml->xpath('//yweather:forecast[2]');
$ad = $secondForecast[0]->attributes();
$fhigh = (string) $ad->high;
$flow = (string) $ad->low;
$ftemptype = (string) $ad->text;
$fdate = (string) $ad->date;
echo "High: {$fhigh} Low: {$flow} Type: {$ftemptype} Date: {$fdate}\n";
High: 21 Low: 11 Type: Sunny Date: 24 May 2013
Upvotes: 1
Reputation: 3586
Probably the easiest thing to do is use a SimpleXMLIterator, which provides a simple interface to traverse your xml data. You would create the iterator, get the children, and then use next
to move from one to the next.
Upvotes: 0