Trying to pull in elements from Yahoo Weather XML - php

Trying to pull a value from the sunrise element from [yweather:astronomy] in the Yahoo XML Doc.
Tried various combinations along the lines of:
echo $yweather->astronomy == 'sunrise';
Is pulling a value from the sunrise element the right terminology? Struggling to find much in the way of help using this terminology on the web.
The remainder of the code is functioning as I wish
Yahoo XML Doc - snippet
<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 - New York, NY</title>
<link>
http://us.rd.yahoo.com/dailynews/rss/weather/New_York__NY/*http://weather.yahoo.com/forecast/USNY0996_f.html
</link>
<description>Yahoo! Weather for New York, NY</description>
<language>en-us</language>
<lastBuildDate>Mon, 12 Dec 2011 1:50 pm EST</lastBuildDate>
<ttl>60</ttl>
<yweather:location city="New York" region="NY" country="US"/>
<yweather:units temperature="F" distance="mi" pressure="in" speed="mph"/>
<yweather:wind chill="40" direction="0" speed="5"/>
<yweather:atmosphere humidity="37" visibility="10" pressure="30.54" rising="2"/>
<yweather:astronomy sunrise="7:09 am" sunset="4:26 pm"/>
rssweather.php
<?php
// Get XML data from source
$feed = file_get_contents("http://weather.yahooapis.com/forecastrss?p=USNY0996&u=f");
// Check to ensure the feed exists
if(!$feed){
die('Weather not found! Check feed URL');
}
$xml = new SimpleXmlElement($feed);
foreach ($xml->channel as $entry){
echo "<strong>Description</strong> ";
echo $entry->description;
echo "<br /><strong>Collected on</strong> ";
echo $entry->lastBuildDate;
//Use that namespace
$yweather = $entry->children("http://xml.weather.yahoo.com/ns/rss/1.0");
echo "<br /><strong>Sunrise</strong> ";
echo $yweather->astronomy == 'sunrise';
}
>?

My final solution
// Get and return sunrise time
function get_sunrise_time(SimpleXMLElement $xml) {
$weather['sunrise'] = $xml->channel->children('yweather', TRUE)->astronomy[1]->attributes()->sunrise;
return $weather;
}

Related

How to get values from mix of namespace and non-namespace XML with

Given the XML and related PHP, below how can I get the namespaced values in the same way that I'm able to get the non-namespaced values? I've been referring to a number of other SE QAs about this, but can't seem to get it right. An help is appreciated. :)
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:psg="http://b3000.example.net:3000/psg_namespace/">
<channel>
<title>Example</title>
<description>example stuff</description>
<item>
<psg:eventId>406589</psg:eventId>
<psg:duration>3482</psg:duration>
</item>
</channel>
</rss>
$xml = new SimpleXMLElement($source, null, true);
foreach($xml->channel->item as $entry){
echo $entry->title; // This works
echo $entry->description; // This works
echo $entry->item->duration // Pseudo of what I need
}
How to get Duration? My attempts with variations such as this have failed
$namespaces = $item->getNameSpaces(true);
$psg = $item->children($namespaces['psg']);
Update
While it wasn't the answer I was actually looking for, I have to accept the first answer that got me trying things leading to the actual problem - "operator error"! This DOES work....my problem was in trying to figure it out, I was debugging with echo print_r($psg, true). That was showing the result as a SimpleXmlObject, which then got me chasing how to get those properties - All I had to do was assign the property instead of echoing it.
foreach($xml->channel->item as $entry){
$psg = $item->children($ns['psg']);
$title = (string) $item->title;
$duration = (string) $psg->duration;
}
One way to achieve this is to use a combination of XPath with namespaces:
$xml = new SimpleXMLElement($source, null, true);
$xml->registerXPathNamespace('psg', 'http://b3000.example.net:3000/psg_namespace/');
foreach ($xml->xpath('//item/psg:duration') as $duration) {
echo $duration, PHP_EOL;
}
If you don't want to declare the namespace literally, you can retrieve it from the document and add it/them dynamically:
foreach ($xml->getDocNamespaces() as $key => $namespace) {
$xml->registerXPathNamespace($key, $namespace);
}

To get xml node value using php

I want to get the value present in xml node for that I written following code.
The code aim is to get
1.Board value,
2.Address->City value,
3.Photo->PropertyPhoto->SequenceId value.
Code is:
//some code
$fsp = $xml->saveXML();
echo $fsp; //it's output is given below
$s = simplexml_import_dom($fsp);
echo $s->PropertyDetails[0]->Board;
echo $s->PropertyDetails[0]->Address->City;
echo $s->PropertyDetails[0]->Photo->PropertyPhoto->SequenceId;
OUTPUT OF echo $fsp is:
<?xml version="1.0" encoding="UTF-8"?>
<PropertyDetails ID="13953882" LastUpdated="Thu, 09 Jan 2014 01:43:48 GMT">
<ListingID>188691</ListingID>
<Board>117</Board>
<Address>
<StreetAddress>B LOCAL RD</StreetAddress>
<AddressLine1>B LOCAL RD</AddressLine1>
<City>PORT REXTON</City>
<Province>Newfoundland & Labrador</Province>
<PostalCode>A0C2H0</PostalCode>
<Country>Canada</Country>
</Address>
<Photo>
<PropertyPhoto>
<SequenceId>1</SequenceId>
</PropertyPhoto>
<PropertyPhoto>
<SequenceId>12</SequenceId>
</PropertyPhoto>
</Photo>
<ViewType>Ocean view</ViewType>
It doesn't given any output.
Output required is:
117
PORT REXTON
1,12
Help me.
A couple things I see here. First of all, your XML is not properly formatted. Your PropertyDetails tag is not closed. So close that out, and instead of using a DOMDocument, use the SimpleXMLElement class.
First your XML needs to corrected like thus:
<?xml version="1.0" encoding="UTF-8"?>
<PropertyDetails ID="13953882" LastUpdated="Thu, 09 Jan 2014 01:43:48 GMT">
<ListingID>188691</ListingID>
<Board>117</Board>
<Address>
<StreetAddress>B LOCAL RD</StreetAddress>
<AddressLine1>B LOCAL RD</AddressLine1>
<City>PORT REXTON</City>
<Province>Newfoundland & Labrador</Province>
<PostalCode>A0C2H0</PostalCode>
<Country>Canada</Country>
</Address>
<Photo>
<PropertyPhoto>
<SequenceId>1</SequenceId>
</PropertyPhoto>
<PropertyPhoto>
<SequenceId>12</SequenceId>
</PropertyPhoto>
</Photo>
<ViewType>Ocean view</ViewType>
</PropertyDetails>
Notice the last line.
Now use SimpleXMLElement and you will be close to accessing the way you want.
$s = new SimpleXMLElement($fsp);
echo $s->Board;
echo $s->Address->City;
$sequence_ids = array();
foreach($s->Photo->PropertyPhoto as $PropertyPhoto)
$sequence_ids[] = $PropertyPhoto->SequenceId;
echo implode(',',$sequence_ids);
Since is your root node in the XML, you dont need to access it via ->PropertyDetails[0]. It knows.
Hope this helps.
First load the xml from the string within your var:
$doc = new DOMDocument();
$doc->load($fsp);
apidoc here: http://www.php.net/manual/en/domdocument.loadxml.php
And then read the tags requested:
//board
$boards = $doc->getElementsByTagName('Board');
echo $boards[0]->nodeValue, PHP_EOL;
//city
$cities = $doc->getElementsByTagName('City');
echo $cities[0]->nodeValue, PHP_EOL;
//sequence ids
$arrIds = array();
foreach ($doc->getElementsByTagName('SequenceId') as $sid) $arrIds[] = $sid->nodeValue;
echo implode(',', $arrIds);
This assumes you only have only one listing within your file! Otherwise you have to do the tag-lookups depending on parent-nodes (not on global document).
Hope this helps!

Parse XML namespaces with php SimpleXML

I know this has been asked many many times but I haven't been able to get any of the suggestions to work with my situation and I have searched the web and here and tried everything and anything and nothing works. I just need to parse this XML with the namespace cap: and just need four entries from it.
<?xml version="1.0" encoding="UTF-8"?>
<entry>
<id>http://alerts.weather.gov/cap/wwacapget.php?x=TX124EFFB832F0.SpecialWeatherStatement.124EFFB84164TX.LUBSPSLUB.ac20a1425c958f66dc159baea2f9e672</id>
<updated>2013-05-06T20:08:00-05:00</updated>
<published>2013-05-06T20:08:00-05:00</published>
<author>
<name>w-nws.webmaster#noaa.gov</name>
</author>
<title>Special Weather Statement issued May 06 at 8:08PM CDT by NWS</title>
<link href="http://alerts.weather.gov/cap/wwacapget.php?x=TX124EFFB832F0.SpecialWeatherStatement.124EFFB84164TX.LUBSPSLUB.ac20a1425c958f66dc159baea2f9e672"/>
<summary>...SIGNIFICANT WEATHER ADVISORY FOR COCHRAN AND BAILEY COUNTIES... AT 808 PM CDT...NATIONAL WEATHER SERVICE DOPPLER RADAR INDICATED A STRONG THUNDERSTORM 30 MILES NORTHWEST OF MORTON...MOVING SOUTHEAST AT 25 MPH. NICKEL SIZE HAIL...WINDS SPEEDS UP TO 40 MPH...CONTINUOUS CLOUD TO GROUND LIGHTNING...AND BRIEF MODERATE DOWNPOURS ARE POSSIBLE WITH</summary>
<cap:event>Special Weather Statement</cap:event>
<cap:effective>2013-05-06T20:08:00-05:00</cap:effective>
<cap:expires>2013-05-06T20:45:00-05:00</cap:expires>
<cap:status>Actual</cap:status>
<cap:msgType>Alert</cap:msgType>
<cap:category>Met</cap:category>
<cap:urgency>Expected</cap:urgency>
<cap:severity>Minor</cap:severity>
<cap:certainty>Observed</cap:certainty>
<cap:areaDesc>Bailey; Cochran</cap:areaDesc>
<cap:polygon>34.19,-103.04 34.19,-103.03 33.98,-102.61 33.71,-102.61 33.63,-102.75 33.64,-103.05 34.19,-103.04</cap:polygon>
<cap:geocode>
<valueName>FIPS6</valueName>
<value>048017 048079</value>
<valueName>UGC</valueName>
<value>TXZ027 TXZ033</value>
</cap:geocode>
<cap:parameter>
<valueName>VTEC</valueName>
<value>
</value>
</cap:parameter>
</entry>
I am using simpleXML and I have a small simple test script set up and it works great for parsing regular elements. I can't for the dickens of me find or get a way to parse the elements with the namespaces.
Here is a small sample test script with code I am using and works great for parsing simple elements. How do I use this to parse namespaces? Everything I've tried doesn't work. I need it to be able to create variables so I can be able to embed them in HTML for style.
<?php
$html = "";
// Get the XML Feed
$data = "http://alerts.weather.gov/cap/tx.php?x=1";
// load the xml into the object
$xml = simplexml_load_file($data);
for ($i = 0; $i < 10; $i++){
$title = $xml->entry[$i]->title;
$summary = $xml->entry[$i]->summary;
$html .= "<p><strong>$title</strong></p><p>$summary</p><hr/>";
}
echo $html;
?>
This works fine for parsing regular elements but what about the ones with the cap: namespace under the entry parent?
<?php
ini_set('display_errors','1');
$html = "";
$data = "http://alerts.weather.gov/cap/tx.php?x=1";
$entries = simplexml_load_file($data);
if(count($entries)):
//Registering NameSpace
$entries->registerXPathNamespace('prefix', 'http://www.w3.org/2005/Atom');
$result = $entries->xpath("//prefix:entry");
//echo count($asin);
//echo "<pre>";print_r($asin);
foreach ($result as $entry):
$title = $entry->title;
$summary = $entry->summary;
$html .= "<p><strong>$title</strong></p><p>$summary</p>$event<hr/>";
endforeach;
endif;
echo $html;
?>
Any help would be greatly appreciated.
-Thanks
I have given same type of answer here - solution to your question
You just need to register Namespace and then you can work normally with simplexml_load_file and XPath
<?php
$data = "http://alerts.weather.gov/cap/tx.php?x=1";
$entries = file_get_contents($data);
$entries = new SimpleXmlElement($entries);
if(count($entries)):
//echo "<pre>";print_r($entries);die;
//alternate way other than registring NameSpace
//$asin = $asins->xpath("//*[local-name() = 'ASIN']");
$entries->registerXPathNamespace('prefix', 'http://www.w3.org/2005/Atom');
$result = $entries->xpath("//prefix:entry");
//echo count($asin);
//echo "<pre>";print_r($result);die;
foreach ($result as $entry):
//echo "<pre>";print_r($entry);die;
$dc = $entry->children('urn:oasis:names:tc:emergency:cap:1.1');
echo $dc->event."<br/>";
echo $dc->effective."<br/>";
echo "<hr>";
endforeach;
endif;
That's it.
Here's an alternative solution:
<?php
$xml = <<<XML
<?xml version = '1.0' encoding = 'UTF-8' standalone = 'yes'?>
<?xml-stylesheet href='http://alerts.weather.gov/cap/capatom.xsl' type='text/xsl'?>
<!--
This atom/xml feed is an index to active advisories, watches and warnings
issued by the National Weather Service. This index file is not the complete
Common Alerting Protocol (CAP) alert message. To obtain the complete CAP
alert, please follow the links for each entry in this index. Also note the
CAP message uses a style sheet to convey the information in a human readable
format. Please view the source of the CAP message to see the complete data
set. Not all information in the CAP message is contained in this index of
active alerts.
-->
<feed
xmlns = 'http://www.w3.org/2005/Atom'
xmlns:cap = 'urn:oasis:names:tc:emergency:cap:1.1'
xmlns:ha = 'http://www.alerting.net/namespace/index_1.0'
>
<!-- http-date = Tue, 07 May 2013 04:14:00 GMT -->
<id>http://alerts.weather.gov/cap/tx.atom</id>
<logo>http://alerts.weather.gov/images/xml_logo.gif</logo>
<generator>NWS CAP Server</generator>
<updated>2013-05-06T23:14:00-05:00</updated>
<author>
<name>w-nws.webmaster#noaa.gov</name>
</author>
<title>Current Watches, Warnings and Advisories for Texas Issued by the National Weather Service</title>
<link href='http://alerts.weather.gov/cap/tx.atom'/>
<entry>
<id>http://alerts.weather.gov/cap/wwacapget.php?x=TX124EFFB8AA78.FireWeatherWatch.124EFFD70270TX.EPZRFWEPZ.1716207877d94d15d43d410892b9f175</id>
<updated>2013-05-06T23:14:00-05:00</updated>
<published>2013-05-06T23:14:00-05:00</published>
<author>
<name>w-nws.webmaster#noaa.gov</name>
</author>
<title>Fire Weather Watch issued May 06 at 11:14PM CDT until May 08 at 10:00PM CDT by NWS</title>
<link href="http://alerts.weather.gov/cap/wwacapget.php?x=TX124EFFB8AA78.FireWeatherWatch.124EFFD70270TX.EPZRFWEPZ.1716207877d94d15d43d410892b9f175"/>
<summary>...CRITICAL FIRE CONDITIONS EXPECTED WEDNESDAY ACROSS FAR WEST TEXAS AND THE SOUTHWEST NEW MEXICO LOWLANDS... .WINDS ALOFT WILL STRENGTHEN OVER THE REGION EARLY THIS WEEK...AHEAD OF AN UPPER LEVEL TROUGH FORECAST TO MOVE THROUGH NEW MEXICO AND TEXAS ON WEDNESDAY. SURFACE LOW PRESSURE WILL ALSO DEVELOP TO OUR EAST AS THE TROUGH APPROACHES. THIS COMBINATION WILL RESULT</summary>
<cap:event>Fire Weather Watch</cap:event>
<cap:effective>2013-05-06T23:14:00-05:00</cap:effective>
<cap:expires>2013-05-08T22:00:00-05:00</cap:expires>
<cap:status>Actual</cap:status>
<cap:msgType>Alert</cap:msgType>
<cap:category>Met</cap:category>
<cap:urgency>Future</cap:urgency>
<cap:severity>Moderate</cap:severity>
<cap:certainty>Possible</cap:certainty>
<cap:areaDesc>El Paso; Hudspeth</cap:areaDesc>
<cap:polygon></cap:polygon>
<cap:geocode>
<valueName>FIPS6</valueName>
<value>048141 048229</value>
<valueName>UGC</valueName>
<value>TXZ055 TXZ056</value>
</cap:geocode>
<cap:parameter>
<valueName>VTEC</valueName>
<value>/O.NEW.KEPZ.FW.A.0018.130508T1900Z-130509T0300Z/</value>
</cap:parameter>
</entry>
<entry>
<id>http://alerts.weather.gov/cap/wwacapget.php?x=TX124EFFABB2F0.AirQualityAlert.124EFFC750DCTX.HGXAQAHGX.7f2cf548a67d403f0541492b2804d621</id>
<updated>2013-05-06T14:16:00-05:00</updated>
<published>2013-05-06T14:16:00-05:00</published>
<author>
<name>w-nws.webmaster#noaa.gov</name>
</author>
<title>Air Quality Alert issued May 06 at 2:16PM CDT by NWS</title>
<link href="http://alerts.weather.gov/cap/wwacapget.php?x=TX124EFFABB2F0.AirQualityAlert.124EFFC750DCTX.HGXAQAHGX.7f2cf548a67d403f0541492b2804d621"/>
<summary>...OZONE ACTION DAY FOR TUESDAY... THE TEXAS COMMISSION ON ENVIRONMENTAL QUALITY (TCEQ)...HAS ISSUED AN OZONE ACTION DAY FOR THE HOUSTON...GALVESTON...AND BRAZORIA AREAS FOR TUESDAY...MAY 7 2013. ATMOSPHERIC CONDITIONS ARE EXPECTED TO BE FAVORABLE FOR PRODUCING HIGH LEVELS OF OZONE POLLUTION IN THE HOUSTON...GALVESTON AND</summary>
<cap:event>Air Quality Alert</cap:event>
<cap:effective>2013-05-06T14:16:00-05:00</cap:effective>
<cap:expires>2013-05-07T19:15:00-05:00</cap:expires>
<cap:status>Actual</cap:status>
<cap:msgType>Alert</cap:msgType>
<cap:category>Met</cap:category>
<cap:urgency>Unknown</cap:urgency>
<cap:severity>Unknown</cap:severity>
<cap:certainty>Unknown</cap:certainty>
<cap:areaDesc>Brazoria; Galveston; Harris</cap:areaDesc>
<cap:polygon></cap:polygon>
<cap:geocode>
<valueName>FIPS6</valueName>
<value>048039 048167 048201</value>
<valueName>UGC</valueName>
<value>TXZ213 TXZ237 TXZ238</value>
</cap:geocode>
<cap:parameter>
<valueName>VTEC</valueName>
<value></value>
</cap:parameter>
</entry>
</feed>
XML;
$sxe = new SimpleXMLElement($xml);
$capFields = $sxe->entry->children('cap', true);
echo "Event: " . (string) $capFields->event . "\n";
echo "Effective: " . (string) $capFields->effective . "\n";
echo "Expires: " . (string) $capFields->expires . "\n";
echo "Severity: " . (string) $capFields->severity . "\n";
Output:
Event: Fire Weather Watch
Effective: 2013-05-06T23:14:00-05:00
Expires: 2013-05-08T22:00:00-05:00
Severity: Moderate

How can I extract data from XML to PHP using SimpleXML and echo?

I've successfully integrated the LinkedIn API with my website, but I'm struggling to extract information from the XML. At the moment I'm just trying to print it out so I can proceed to use the user's information once they have logged in and given permission.
Below is the format of the XML, and further down is the code I am using to extract the information. The "first name", "last name" and "headline" calls work perfectly, but where an element has sub-headings, nothing is printed out. I've tried using
echo 'Positions: ' . $xml->{'positions:(title)'};
but it doesn't work.
Here is the XML:
<person>
<id>
<first-name />
<last-name />
<headline>
<location>
<name>
<country>
<code>
</country>
</location>
<industry>
<summary/>
<positions total="">
<position>
<id>
<title>
<summary>
<start-date>
<year>
<month>
</start-date>
<is-current>
<company>
<name>
</company>
</position>
</person>
This is the code I've been using to try to extract the information. I know I have to include the sub-heading somehow but I just don't know how!
echo 'First Name: ' . $xml->{'first-name'};
echo '<br/>';
echo 'Last Name: ' . $xml->{'last-name'};
echo '<br/>';
echo 'Headline: ' . $xml->{'headline'};
echo '<br/>';
echo 'Positions: ' . $xml->{'positions'};
Any help would be greatly appreciated, thanks for reading!
Using SimpleXML, you'd access the LinkedIn XML data properties as follows:
Anything with a dash in the property gets {}, so first-name becomes:
$xml->{'first-name'}
Anything without a dash such as headline, is referenced like:
$xml->headline
Anything that is a collection, such as positions, is referenced like:
foreach($xml-positions as $position) {
echo $position->title;
echo $position->{'is-current'};
}
Your XML is not valid, its not well formed. Anyway here's a sample XML and how to use it.
$v = <<<ABC
<vitrine>
<canal>Hotwords</canal>
<product id="0">
<descricao>MP3 Apple iPod Class...</descricao>
<loja>ApetreXo.com</loja>
<preco>à vista R$765,22</preco>
<urlImagem>http://im</urlImagem>
<urlProduto>http://</urlProduto>
</product>
</vitrine>
ABC;
$xml = simplexml_load_string($v);
foreach ($xml->product as $c){
echo $c->loja; //echoing out value of 'loja'
}
Try to use PHP's XML Parser instead:
http://www.php.net/manual/en/function.xml-parse.php
Tried Paul's answer above for:
foreach($xml-positions as $position) {
echo $position->title;
echo $position->{'is-current'};
}
didn't work for me - so I used this - not as elegant but works
for($position_num = 0; $position_num < 10;$position_num++){
echo $xml->positions->position[$position_num]->company->name;
}
Your XML is not well-formed... there are several elements without close tags. So we have no way to know for sure the structure of your XML. (You can't do that in XML like you can in HTML.)
That being said, assuming that <person> is the context node, you can probably get the content of the <title> element using an XPath expression, as in
$xml->xpath('positions/position/title');
I'm assuming $xml is a SimpleXMLElement object.

How to get the tag "<yweather:condition>" from Yahoo Weather RSS in PHP?

<?php
$doc = new DOMDocument();
$doc->load('http://weather.yahooapis.com/forecastrss?p=VEXX0024&u=c');
$channel = $doc->getElementsByTagName("channel");
foreach($channel as $chnl)
{
$item = $chnl->getElementsByTagName("item");
foreach($item as $itemgotten)
{
$describe = $itemgotten->getElementsByTagName("description");
$description = $describe->item(0)->nodeValue;
echo $description;
}
}
?>
And as you can see is a simple script who return the content of the tag from the above url. The thing is that i dont need that content, i need the one who is inside the tag . I need the attributes code, temp, text. How do i do that simple with my actual code? Thanks
Ex of the tag content:
<yweather:condition text="Partly Cloudy" code="30" temp="30" date="Fri, 16 Jul 2010 8:30 am AST" />
Something like:
echo $itemgotten->getElementsByTagNameNS(
"http://xml.weather.yahoo.com/ns/rss/1.0","condition")->item(0)->
getAttribute("temp");
The key is that you have to use getElementsByTagNameNS instead of getElementsByTagName and specify "http://xml.weather.yahoo.com/ns/rss/1.0" as the namespace.
You know yweather is a shortcut for http://xml.weather.yahoo.com/ns/rss/1.0 because the XML file includes a xmls attribute:
<rss version="2.0" xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0"
xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#">
How about:
DOMElement::getAttribute — Returns value of attribute
And if you need to get anything with namespaces, there is corresponding methods ending in NS.

Categories