Displaying weather XML from NOAA using PHP and XSLT

Displaying weather XML from NOAA using PHP and XSLT

NOAA now has XML feeds with weather forecasts based upon your latitude and longitude—allowing you to get a forecast much closer to your house if you wish. The URL is http://forecast. weather.gov/MapClick.php?lat=38.86059&lon=-121.491393&FcstType=dwml, where you substitute your own latitude and longitude for those in the example. Using XSLT, the feed can be quickly styled into something useable on a web page. The XSL style sheet (noaa.xsl) follows:

  1. <?xml version=“1.0” encoding=“utf-8”?>
  2. <xsl:style sheet version=“1.0” xmlns:xsl=“http://www.w3.org/1999/XSL/Transform” xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance” exclude-result-prefixes=“xsi”>
  3. <xsl:output method=“xml” omit-xml-declaration=“yes” encoding=“utf-8”/>
  4. <xsl:variable name=“timelayoutkey” select=“/dwml/data/parameters/weather/@time-layout” />
  5. <xsl:template match=”/”>
  6. <h2>Weather Forecast <xsl:value-of select=“dwml/data/location/area-description” /></h2>
  7. <p>
  8. <xsl:apply-templates select=“dwml/data/parameters/hazards/hazard-conditions/hazard” />
  9. <xsl:text>More information on the forecast is at the </xsl:text>
  10. <a href=“{dwml/data/moreWeatherInformation}”><xsl:text>National Weather Service site</xsl:text></a>
  11. <xsl:text>. Forecast created </xsl:text>
  12. <xsl:value-of select=“dwml/head/product/creation-date” />
  13. <xsl:text>.</xsl:text>
  14. </p>
  15. <xsl:call-template name=“forloop”>
  16. <xsl:with-param name=“first” select=“1” />
  17. <xsl:with-param name=“last” select=“substring($timelayoutkey,9,2)” />
  18. </xsl:call-template>
  19. </xsl:template>
  20. <xsl:template name=“forloop” >
  21. <xsl:param name=“first” />
  22. <xsl:param name=“last” />
  23. <p class=“weather”>
  24. <img src=“{dwml/data/parameters/conditions-icon/icon-link[$first]}” alt=“{dwml/data/parameters/weather/weather-conditions[$first]/@weather-summary}” />
  25. <span><strong><xsl:value-of select=“dwml/data/time-layout[layout-key = $timelayoutkey]/start-valid-time[$first]/@period-name” /></strong><xsl:text>: </xsl:text>
  26. <xsl:value-of select=“dwml/data/parameters/wordedForecast/text[$first]” /></span>
  27. </p>
  28. <xsl:if test=“$first &lt; $last“>
  29. <xsl:call-template name=“forloop”>
  30. <xsl:with-param name=“last” select=“$last” />
  31. <xsl:with-param name=“first” select=“$first + 1” />
  32. </xsl:call-template>
  33. </xsl:if>
  34. </xsl:template>
  35. <xsl:template match=“hazard”>
  36. <a href=“{hazardTextURL}”><em><xsl:value-of select=”@headline”/></em></a><xsl:text>. </xsl:text>
  37. </xsl:template>
  38. </xsl:style sheet>

If you haven't coded an XSLT style sheet before, you should read about the language before attempting to alter this. Lines 20–34 may look a bit odd—there is no “for” loop in XSLT (at least not in XSLT 1.0, which is what the PHP processor uses). This sheet uses tail recursion to mimic a for loop. Line 28 checks to see if any more work is needed. If so, the template calls itself, but with a different “first” parameter. In XSLT, variables and parameters, once assigned, cannot be changed, necessitating things like recursive calls.

  1. <?php
  2. $xsl = new DOMDocument ;
  3. $xsl->load($_SERVER['DOCUMENT_ROOT'].'/inc/noaa.xsl') ;
  4. $xslProc = new XSLTProcessor() ;
  5. $xslProc->importStylesheet($xsl) ;
  6. $xmldoc = new DOMDocument ;
  7. $xmldoc->load('http://forecast. weather.gov/MapClick.php?lat=38.86059&lon=-121.491393&FcstType=dwml') ;
  8. echo $xslProc->transformToXML($xmldoc) ;
  9. ?>

To apply an XSL style sheet in PHP, you need to load the style sheet into an xml document, then start up an XSLTProcessor and load the style sheet into that. As you see, the PHP is very simple—all the formatting is done in the style sheet. Learning XSLT is worthwhile if you are transforming XML data into another form (e. g., into a web document). The learning curve is a bit steep, but the code is much more compact and easier to maintain. XSL forces you to code cleanly.

Creative Commons License This work by Rory Jaffe is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.

Tags: 

3 Comments

Do you have a working example?

I get this in XAMPP/PHP (my main php file=dwml.php):
( ! ) Warning: DOMDocument::load() [domdocument.load]: Specification mandate value for attribute sheet in C:/xampp/htdocs/at_work/noaa.xsl, line: 2 in C:\xampp\htdocs\at_work\dwml.php on line 3
Call Stack
# Time Memory Function Location
1 0.0012 336592 {main}( ) ..\dwml.php:0

does not work in my xampp-php

Warning: DOMDocument::load() [domdocument.load]: Specification mandate value for attribute sheet in C:/xampp/htdocs/at_work/noaa.xsl, line: 2 in C:\xampp\htdocs\at_work\dwml.php on line 3

Do you have a working example

Do you have a working example? My XAMPP is showing errors, even though it is using the XSL DLL