]> Wikimedia Canada | Git repositories - eccc_to_commons.git/blobdiff - monthly_to_commons.xslt
Complete process from ECCC website to Commons files generation
[eccc_to_commons.git] / monthly_to_commons.xslt
diff --git a/monthly_to_commons.xslt b/monthly_to_commons.xslt
new file mode 100644 (file)
index 0000000..4f1fa9e
--- /dev/null
@@ -0,0 +1,576 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- monthly_to_commons.xslt - Convert Environment and Climate change Canada
+                               historical XML data into a JSON format suitable
+                               for Wikimedia Commons.
+     Copyright (C) 2019-2020  Pierre Choffet
+
+     This program is free software: you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published by
+     the Free Software Foundation, either version 3 of the License, or
+     (at your option) any later version.
+
+     This program is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+     GNU General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with this program.  If not, see <http://www.gnu.org/licenses/>.
+     -->
+
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+       <xsl:output method="text" encoding="utf-8" />
+
+       <xsl:template match="/climatedata">
+               <xsl:variable name="station-name">
+                       <xsl:call-template name="camel-case">
+                               <xsl:with-param name="text" select="/climatedata/stationinformation/name/text()" />
+                       </xsl:call-template>
+               </xsl:variable>
+               <xsl:variable name="province-name">
+                       <xsl:call-template name="camel-case">
+                               <xsl:with-param name="text" select="/climatedata/stationinformation/province/text()" />
+                       </xsl:call-template>
+               </xsl:variable>
+
+               <xsl:text>{
+       "license": "CC0-1.0",
+       "description": {
+               "en": "</xsl:text><xsl:value-of select="$station-name" /><xsl:text> Monthly Weather Data",
+               "fr": "Données météorologiques mensuelles de </xsl:text><xsl:value-of select="$station-name" /><xsl:text>"
+       },
+       "sources": "[https://climate.weather.gc.ca/ Environment and Climate Change Canada]",
+       "categories": "[Category:Environment and Climate Change Canada Monthly Weather Data] [Category:Weather Data in </xsl:text>
+       <xsl:value-of select="$province-name" />
+       <xsl:text>]",
+       "schema": {
+               "fields": [
+                       {
+                                       "name": "date",
+                                       "type": "string",
+                                       "title": {
+                                                       "ar": "تاريخ",
+                                                       "ca": "Data",
+                                                       "da": "Dato",
+                                                       "de": "Datum",
+                                                       "en": "Date",
+                                                       "es": "Fecha",
+                                                       "fr": "Date",
+                                                       "ru": "Дата",
+                                                       "sr": "Датум"
+                                       }
+                       },
+                       {
+                                       "name": "avgHighTemp",
+                                       "type": "number",
+                                       "title": {
+                                                       "ca": "Mitjana de temps. altes",
+                                                       "da": "Gennemsnitlig højeste temperatur",
+                                                       "de": "Durchschnittliche Höchsttemperatur",
+                                                       "en": "Average high temp",
+                                                       "es": "Promedio de temps. altas",
+                                                       "fr": "Température maximale moyenne",
+                                                       "ru": "Средняя высшая темп",
+                                                       "sr": "Просечна виша температура"
+                                       }
+                       },
+                       {
+                                       "name": "avgLowTemp",
+                                       "type": "number",
+                                       "title": {
+                                                       "ca": "Mitjana de temps. baixes",
+                                                       "da": "Gennemsnitlige laveste temperatur",
+                                                       "de": "Durchschnittliche Tiefsttemperatur",
+                                                       "en": "Average low temp",
+                                                       "es": "Promedio de temps. bajas",
+                                                       "fr": "Température minimale moyenne",
+                                                       "ru": "Средняя нижняя темп",
+                                                       "sr": "Просечна нижа температура"
+                                       }
+                       },
+                       {
+                                       "name": "avgTemp",
+                                       "type": "number",
+                                       "title": {
+                                                       "en": "Average temperature",
+                                                       "fr": "Température moyenne"
+                                       }
+                       },
+                       {
+                                       "name": "extHighTemp",
+                                       "type": "number",
+                                       "title": {
+                                                       "en": "Highest daily maximum temperature",
+                                                       "fr": "Température maximale quotidienne la plus élevée"
+                                       }
+                       },
+                       {
+                                       "name": "extLowTemp",
+                                       "type": "number",
+                                       "title": {
+                                                       "en": "Lowest daily minimal temperature",
+                                                       "fr": "Température minimale la plus basse"
+                                       }
+                       },
+                       {
+                                       "name": "precipTotalRain",
+                                       "type": "number",
+                                       "title": {
+                                                       "en": "Total rainfall (mm)",
+                                                       "fr": "Pluie totale (mm)"
+                                       }
+                       },
+                       {
+                                       "name": "precipTotalSnow",
+                                       "type": "number",
+                                       "title": {
+                                                       "en": "Total snowfall (cm)",
+                                                       "fr": "Neige totale (cm)"
+                                       }
+                       },
+                       {
+                                       "name": "precipTotal",
+                                       "type": "number",
+                                       "title": {
+                                                       "en": "Total précipitation (mm)",
+                                                       "fr": "Précipitations totale (mm)"
+                                       }
+                       },
+                       {
+                                       "name": "snowGrndLastDay",
+                                       "type": "number",
+                                       "title": {
+                                                       "en": "Snow on the ground on the last day (cm)",
+                                                       "fr": "Neige au sol le dernier jour (cm)"
+                                       }
+                       },
+                       {
+                                       "name": "windDirMaxGust",
+                                       "type": "number",
+                                       "title": {
+                                                       "en": "Direction of maximum gust (10's deg/tens of degrees)",
+                                                       "fr": "Direction de la rafale maximale (10's deg/dizaines de degrés)"
+                                       }
+                       },
+                       {
+                                       "name": "windSpeedMaxGust",
+                                       "type": "number",
+                                       "title": {
+                                                       "en": "Speed of maximum gust (km/h)",
+                                                       "fr": "Vitesse de la rafale maximale (km/h)"
+                                       }
+                       }
+               ]
+       },
+       "data": [</xsl:text>
+               <xsl:apply-templates select="stationdata" />
+               <xsl:text>]}</xsl:text>
+       </xsl:template>
+
+       <xsl:template match="stationdata">
+               <!-- TODO: Check element has at least one data? -->
+               <!-- Set date -->
+               <xsl:text>["</xsl:text>
+               <xsl:value-of select="@year" />
+               <xsl:text>-</xsl:text>
+               <xsl:value-of select="format-number(@month, '00')" />
+               <xsl:text>"</xsl:text>
+
+               <!-- Set meanmaxtemp -->
+               <xsl:text>, </xsl:text>
+               <xsl:apply-templates select="meanmaxtemp" />
+
+               <!-- Set meanmintemp -->
+               <xsl:text>, </xsl:text>
+               <xsl:apply-templates select="meanmintemp" />
+
+               <!-- Set meanmonthtemp -->
+               <xsl:text>, </xsl:text>
+               <xsl:apply-templates select="meanmonthtemp" />
+
+               <!-- Set extrmaxtemp -->
+               <xsl:text>, </xsl:text>
+               <xsl:apply-templates select="extrmaxtemp" />
+
+               <!-- Set extrmintemp -->
+               <xsl:text>, </xsl:text>
+               <xsl:apply-templates select="extrmintemp" />
+
+               <!-- Set totrain -->
+               <xsl:text>, </xsl:text>
+               <xsl:apply-templates select="totrain" />
+
+               <!-- Set totsnow -->
+               <xsl:text>, </xsl:text>
+               <xsl:apply-templates select="totsnow" />
+
+               <!-- Set totprecip -->
+               <xsl:text>, </xsl:text>
+               <xsl:apply-templates select="totprecip" />
+
+               <!-- Set grndsnowlastday -->
+               <xsl:text>, </xsl:text>
+               <xsl:apply-templates select="grndsnowlastday" />
+
+               <!-- Set dirmaxgust -->
+               <xsl:text>, </xsl:text>
+               <xsl:apply-templates select="dirmaxgust" />
+
+               <!-- Set speedmaxgust -->
+               <xsl:text>, </xsl:text>
+               <xsl:apply-templates select="speedmaxgust" />
+
+
+               <xsl:text>]</xsl:text>
+               <xsl:if test="position() != last()">
+                       <xsl:text>, </xsl:text>
+               </xsl:if>
+       </xsl:template>
+
+       <!-- Process meanmaxtemp -->
+       <xsl:template match="meanmaxtemp">
+               <xsl:choose>
+                       <xsl:when test="not(text())">
+                               <xsl:text>null</xsl:text>
+                       </xsl:when>
+                       <xsl:when test="@flag = 'E'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert estimated meanmaxtemp value</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:when test="@flag = 'I'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert meanmaxtemp value with undocumented "I" flag</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:when test="@flag = 'M'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert available meanmaxtemp marked as missing</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:otherwise>
+                               <xsl:value-of select="text()" />
+                       </xsl:otherwise>
+               </xsl:choose>
+       </xsl:template>
+
+       <!-- Process meanmintemp -->
+       <xsl:template match="meanmintemp">
+               <xsl:choose>
+                       <xsl:when test="not(text())">
+                               <xsl:text>null</xsl:text>
+                       </xsl:when>
+                       <xsl:when test="@flag = 'E'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert estimated meanmintemp value</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:when test="@flag = 'I'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert meanmintemp value with undocumented "I" flag</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:when test="@flag = 'M'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert available meanmintemp marked as missing</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:otherwise>
+                               <xsl:value-of select="text()" />
+                       </xsl:otherwise>
+               </xsl:choose>
+       </xsl:template>
+
+       <!-- Process meanmonthtemp -->
+       <xsl:template match="meanmonthtemp">
+               <xsl:choose>
+                       <xsl:when test="not(text())">
+                               <xsl:text>null</xsl:text>
+                       </xsl:when>
+                       <xsl:when test="@flag = 'E'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert estimated meanmonthtemp value</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:when test="@flag = 'I'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert meanmonthtemp value with undocumented "I" flag</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:when test="@flag = 'M'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert available meanmonthtemp marked as missing</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:otherwise>
+                               <xsl:value-of select="text()" />
+                       </xsl:otherwise>
+               </xsl:choose>
+       </xsl:template>
+
+       <!-- Process extrmaxtemp -->
+       <xsl:template match="extrmaxtemp">
+               <xsl:choose>
+                       <xsl:when test="not(text())">
+                               <xsl:text>null</xsl:text>
+                       </xsl:when>
+                       <xsl:when test="@flag = 'B'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert multiple and estimated extrmaxtemp value</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:when test="@flag = 'E'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert estimated extrmaxtemp value</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:when test="@flag = 'I'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert extrmaxtemp value with undocumented "I" flag</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:when test="@flag = 'M'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert available extrmaxtemp marked as missing</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:when test="@flag = 'S'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert multiple extrmaxtemp value</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:otherwise>
+                               <xsl:value-of select="text()" />
+                       </xsl:otherwise>
+               </xsl:choose>
+       </xsl:template>
+
+       <!-- Process extrmintemp -->
+       <xsl:template match="extrmintemp">
+               <xsl:choose>
+                       <xsl:when test="not(text())">
+                               <xsl:text>null</xsl:text>
+                       </xsl:when>
+                       <xsl:when test="@flag = 'B'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert multiple and estimated extrmintemp value</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:when test="@flag = 'E'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert estimated extrmintemp value</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:when test="@flag = 'I'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert extrmintemp value with undocumented "I" flag</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:when test="@flag = 'M'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert available extrmintemp marked as missing</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:when test="@flag = 'S'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert multiple extrmintemp value</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:otherwise>
+                               <xsl:value-of select="text()" />
+                       </xsl:otherwise>
+               </xsl:choose>
+       </xsl:template>
+
+       <!-- Process totrain -->
+       <xsl:template match="totrain">
+               <xsl:choose>
+                       <xsl:when test="not(text())">
+                               <xsl:text>null</xsl:text>
+                       </xsl:when>
+                       <xsl:when test="contains(text(), '#')">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Discard totrain containing "#"</xsl:message>
+                               <xsl:text>null</xsl:text>
+                       </xsl:when>
+                       <xsl:when test="@flag = 'E'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert estimated totrain value</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:when test="@flag = 'I'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert totrain value with undocumented "I" flag</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:when test="@flag = 'M'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert available totrain marked as missing</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:when test="@flag = 'T'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert traces only totrain value</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:otherwise>
+                               <xsl:value-of select="text()" />
+                       </xsl:otherwise>
+               </xsl:choose>
+       </xsl:template>
+
+       <!-- Process totsnow -->
+       <xsl:template match="totsnow">
+               <xsl:choose>
+                       <xsl:when test="not(text())">
+                               <xsl:text>null</xsl:text>
+                       </xsl:when>
+                       <xsl:when test="text() &lt; 0">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Discard negative totsnow value</xsl:message>
+                               <xsl:text>null</xsl:text>
+                       </xsl:when>
+                       <xsl:when test="@flag = 'E'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert estimated totsnow value</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:when test="@flag = 'I'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert totsnow value with undocumented "I" flag</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:when test="@flag = 'M'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert available totsnow marked as missing</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:when test="@flag = 'T'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert traces only totsnow value</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:otherwise>
+                               <xsl:value-of select="text()" />
+                       </xsl:otherwise>
+               </xsl:choose>
+       </xsl:template>
+
+       <!-- Process totprecip -->
+       <xsl:template match="totprecip">
+               <xsl:choose>
+                       <xsl:when test="not(text())">
+                               <xsl:text>null</xsl:text>
+                       </xsl:when>
+                       <xsl:when test="contains(text(), '#')">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Discard totprecip containing "#"</xsl:message>
+                               <xsl:text>null</xsl:text>
+                       </xsl:when>
+                       <xsl:when test="@flag = 'E'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert estimated totprecip value</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:when test="@flag = 'I'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert totprecip value with undocumented "I" flag</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:when test="@flag = 'M'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert available totprecip marked as missing</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:when test="@flag = 'T'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert traces only totprecip value</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:otherwise>
+                               <xsl:value-of select="text()" />
+                       </xsl:otherwise>
+               </xsl:choose>
+       </xsl:template>
+
+       <!-- Process grndsnowlastday -->
+       <xsl:template match="grndsnowlastday">
+               <xsl:choose>
+                       <xsl:when test="not(text())">
+                               <xsl:text>null</xsl:text>
+                       </xsl:when>
+                       <xsl:when test="@flag = 'E'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert estimated grndsnowlastday value</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:when test="@flag = 'M'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert available grndsnowlastday marked as missing</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:when test="@flag = 'T'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert traces only grndsnowlastday value</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:otherwise>
+                               <xsl:value-of select="text()" />
+                       </xsl:otherwise>
+               </xsl:choose>
+       </xsl:template>
+
+       <!-- Process dirmaxgust -->
+       <xsl:template match="dirmaxgust">
+               <xsl:choose>
+                       <xsl:when test="not(text())">
+                               <xsl:text>null</xsl:text>
+                       </xsl:when>
+                       <xsl:when test="@flag = 'B'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert multiple and estimated dirmaxgust value</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:when test="@flag = 'E'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert estimated dirmaxgust value</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:when test="@flag = 'I'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert dirmaxgust value with undocumented "I" flag</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:when test="@flag = 'M'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert available dirmaxgust marked as missing</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:when test="@flag = 'S'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert multiple dirmaxgust value</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:when test="text() = '36'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert dirmaxgust with a value of "36"</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:otherwise>
+                               <xsl:value-of select="text()" />
+                       </xsl:otherwise>
+               </xsl:choose>
+       </xsl:template>
+
+       <!-- Process speedmaxgust -->
+       <xsl:template match="speedmaxgust">
+               <xsl:choose>
+                       <xsl:when test="not(text())">
+                               <xsl:text>null</xsl:text>
+                       </xsl:when>
+                       <xsl:when test="text() = '&lt;31'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Discard speedmaxgust with value "&lt;31"</xsl:message>
+                               <xsl:text>null</xsl:text>
+                       </xsl:when>
+                       <xsl:when test="@flag = 'B'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert multiple and estimated speedmaxgust value</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:when test="@flag = 'E'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert estimated speedmaxgust value</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:when test="@flag = 'I'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert speedmaxgust value with undocumented "I" flag</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:when test="@flag = 'M'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert available speedmaxgust marked as missing</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:when test="@flag = 'S'">
+                               <xsl:message>WARNING: <xsl:value-of select="../@year" />-<xsl:value-of select="format-number(../@month, '00')" />: Insert multiple speedmaxgust value</xsl:message>
+                               <xsl:value-of select="text()" />
+                       </xsl:when>
+                       <xsl:otherwise>
+                               <xsl:value-of select="text()" />
+                       </xsl:otherwise>
+               </xsl:choose>
+       </xsl:template>
+
+       <!-- Camel case -->
+       <xsl:template name="camel-case">
+               <xsl:param name="text" select="."/>
+               <xsl:variable name="uppercase">ABCDEFGHIJKLMNOPQRSTUVWXYZ</xsl:variable>
+               <xsl:variable name="lowercase">abcdefghijklmnopqrstuvwxyz</xsl:variable>
+               <xsl:variable name="word" select="substring-before(concat($text, ' '), ' ')" />
+
+               <xsl:value-of select="translate(substring($word, 1, 1), $lowercase, $uppercase)" />
+               <xsl:value-of select="translate(substring($word, 2), $uppercase, $lowercase)" />
+
+               <xsl:if test="contains($text, ' ')">
+                       <xsl:text> </xsl:text>
+                       <xsl:call-template name="camel-case">
+                               <xsl:with-param name="text" select="substring-after($text, ' ')"/>
+                       </xsl:call-template>
+               </xsl:if>
+       </xsl:template>
+</xsl:stylesheet>