Displaying weather XML from NOAA

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 stylesheet follows:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <xsl:stylesheet 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:stylesheet>

If you haven't coded an XSLT stylesheet 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 stylesheet in PHP, you need to load the stylesheet into an xml document, then start up an XSLTProcessor and load the stylesheet into that. As you see, the PHP is very simple—all the formatting is done in the stylesheet. 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.

Our home page (thejaffes.org) uses this stylesheet, with some modifications to place the results in a table.

This software is licensed under the CC-GNU GPL. CC-GNU GPL


vacuous-lupine