1 <?xml version=
"1.0" encoding=
"UTF-8"?>
3 <!-- monthly_to_commons.xslt - Convert Environment and Climate change Canada
4 historical XML data into a JSON format suitable
6 Copyright (C) 2019-2020 Pierre Choffet
8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 <xsl:stylesheet version=
"1.0" xmlns:
xsl=
"http://www.w3.org/1999/XSL/Transform">
23 <xsl:output method=
"text" encoding=
"utf-8" />
25 <xsl:template match=
"/climatedata">
26 <xsl:variable name=
"station-name">
27 <xsl:call-template name=
"camel-case">
28 <xsl:with-param name=
"text" select=
"/climatedata/stationinformation/name/text()" />
31 <xsl:variable name=
"province-name">
32 <xsl:call-template name=
"camel-case">
33 <xsl:with-param name=
"text" select=
"/climatedata/stationinformation/province/text()" />
40 "en": "
</xsl:text><xsl:value-of select=
"$station-name" /><xsl:text> Monthly Weather Data",
41 "fr": "Données météorologiques mensuelles de
</xsl:text><xsl:value-of select=
"$station-name" /><xsl:text>"
43 "sources
": "[https://climate.weather.gc.ca/ Environment and Climate Change Canada]
",
44 "categories
": "[Category:Environment and Climate Change Canada Monthly Weather Data] [Category:Weather Data in
</xsl:text>
45 <xsl:value-of select=
"$province-name" />
65 "name": "avgHighTemp",
68 "ca": "Mitjana de temps. altes",
69 "da": "Gennemsnitlig højeste temperatur",
70 "de": "Durchschnittliche Höchsttemperatur",
71 "en": "Average high temp",
72 "es": "Promedio de temps. altas",
73 "fr": "Température maximale moyenne",
74 "ru": "Средняя высшая темп",
75 "sr": "Просечна виша температура"
82 "ca": "Mitjana de temps. baixes",
83 "da": "Gennemsnitlige laveste temperatur",
84 "de": "Durchschnittliche Tiefsttemperatur",
85 "en": "Average low temp",
86 "es": "Promedio de temps. bajas",
87 "fr": "Température minimale moyenne",
88 "ru": "Средняя нижняя темп",
89 "sr": "Просечна нижа температура"
96 "en": "Average temperature",
97 "fr": "Température moyenne"
101 "name": "extHighTemp",
104 "en": "Highest daily maximum temperature",
105 "fr": "Température maximale quotidienne la plus élevée"
109 "name": "extLowTemp",
112 "en": "Lowest daily minimal temperature",
113 "fr": "Température minimale la plus basse"
117 "name": "precipTotalRain",
120 "en": "Total rainfall (mm)",
121 "fr": "Pluie totale (mm)"
125 "name": "precipTotalSnow",
128 "en": "Total snowfall (cm)",
129 "fr": "Neige totale (cm)"
133 "name": "precipTotal",
136 "en": "Total précipitation (mm)",
137 "fr": "Précipitations totale (mm)"
141 "name": "snowGrndLastDay",
144 "en": "Snow on the ground on the last day (cm)",
145 "fr": "Neige au sol le dernier jour (cm)"
149 "name": "windDirMaxGust",
152 "en": "Direction of maximum gust (
10's deg/tens of degrees)",
153 "fr": "Direction de la rafale maximale (
10's deg/dizaines de degrés)"
157 "name": "windSpeedMaxGust",
160 "en": "Speed of maximum gust (km/h)",
161 "fr": "Vitesse de la rafale maximale (km/h)"
167 <xsl:apply-templates select=
"stationdata" />
168 <xsl:text>]}
</xsl:text>
171 <xsl:template match=
"stationdata">
172 <!-- TODO: Check element has at least one data? -->
174 <xsl:text>["
</xsl:text>
175 <xsl:value-of select=
"@year" />
176 <xsl:text>-
</xsl:text>
177 <xsl:value-of select=
"format-number(@month, '00')" />
178 <xsl:text>"</xsl:text>
180 <!-- Set meanmaxtemp -->
181 <xsl:text>, </xsl:text>
182 <xsl:apply-templates select="meanmaxtemp
" />
184 <!-- Set meanmintemp -->
185 <xsl:text>, </xsl:text>
186 <xsl:apply-templates select="meanmintemp
" />
188 <!-- Set meanmonthtemp -->
189 <xsl:text>, </xsl:text>
190 <xsl:apply-templates select="meanmonthtemp
" />
192 <!-- Set extrmaxtemp -->
193 <xsl:text>, </xsl:text>
194 <xsl:apply-templates select="extrmaxtemp
" />
196 <!-- Set extrmintemp -->
197 <xsl:text>, </xsl:text>
198 <xsl:apply-templates select="extrmintemp
" />
201 <xsl:text>, </xsl:text>
202 <xsl:apply-templates select="totrain
" />
205 <xsl:text>, </xsl:text>
206 <xsl:apply-templates select="totsnow
" />
208 <!-- Set totprecip -->
209 <xsl:text>, </xsl:text>
210 <xsl:apply-templates select="totprecip
" />
212 <!-- Set grndsnowlastday -->
213 <xsl:text>, </xsl:text>
214 <xsl:apply-templates select="grndsnowlastday
" />
216 <!-- Set dirmaxgust -->
217 <xsl:text>, </xsl:text>
218 <xsl:apply-templates select="dirmaxgust
" />
220 <!-- Set speedmaxgust -->
221 <xsl:text>, </xsl:text>
222 <xsl:apply-templates select="speedmaxgust
" />
225 <xsl:text>]</xsl:text>
226 <xsl:if test="position() != last()
">
227 <xsl:text>, </xsl:text>
231 <!-- Process meanmaxtemp -->
232 <xsl:template match="meanmaxtemp
">
234 <xsl:when test="not(text())
">
235 <xsl:text>null</xsl:text>
237 <xsl:when test="@flag = 'E'
">
238 <xsl:message>WARNING: <xsl:value-of select="../@year
" />-<xsl:value-of select="format-number(../@month, '
00')
" />: Insert estimated meanmaxtemp value</xsl:message>
239 <xsl:value-of select="text()
" />
241 <xsl:when test="@flag = 'I'
">
242 <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>
243 <xsl:value-of select=
"text()" />
245 <xsl:when test=
"@flag = 'M'">
246 <xsl:message>WARNING:
<xsl:value-of select=
"../@year" />-
<xsl:value-of select=
"format-number(../@month, '00')" />: Insert available meanmaxtemp marked as missing
</xsl:message>
247 <xsl:value-of select=
"text()" />
250 <xsl:value-of select=
"text()" />
255 <!-- Process meanmintemp -->
256 <xsl:template match=
"meanmintemp">
258 <xsl:when test=
"not(text())">
259 <xsl:text>null
</xsl:text>
261 <xsl:when test=
"@flag = 'E'">
262 <xsl:message>WARNING:
<xsl:value-of select=
"../@year" />-
<xsl:value-of select=
"format-number(../@month, '00')" />: Insert estimated meanmintemp value
</xsl:message>
263 <xsl:value-of select=
"text()" />
265 <xsl:when test=
"@flag = 'I'">
266 <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>
267 <xsl:value-of select=
"text()" />
269 <xsl:when test=
"@flag = 'M'">
270 <xsl:message>WARNING:
<xsl:value-of select=
"../@year" />-
<xsl:value-of select=
"format-number(../@month, '00')" />: Insert available meanmintemp marked as missing
</xsl:message>
271 <xsl:value-of select=
"text()" />
274 <xsl:value-of select=
"text()" />
279 <!-- Process meanmonthtemp -->
280 <xsl:template match=
"meanmonthtemp">
282 <xsl:when test=
"not(text())">
283 <xsl:text>null
</xsl:text>
285 <xsl:when test=
"@flag = 'E'">
286 <xsl:message>WARNING:
<xsl:value-of select=
"../@year" />-
<xsl:value-of select=
"format-number(../@month, '00')" />: Insert estimated meanmonthtemp value
</xsl:message>
287 <xsl:value-of select=
"text()" />
289 <xsl:when test=
"@flag = 'I'">
290 <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>
291 <xsl:value-of select=
"text()" />
293 <xsl:when test=
"@flag = 'M'">
294 <xsl:message>WARNING:
<xsl:value-of select=
"../@year" />-
<xsl:value-of select=
"format-number(../@month, '00')" />: Insert available meanmonthtemp marked as missing
</xsl:message>
295 <xsl:value-of select=
"text()" />
298 <xsl:value-of select=
"text()" />
303 <!-- Process extrmaxtemp -->
304 <xsl:template match=
"extrmaxtemp">
306 <xsl:when test=
"not(text())">
307 <xsl:text>null
</xsl:text>
309 <xsl:when test=
"@flag = 'B'">
310 <xsl:message>WARNING:
<xsl:value-of select=
"../@year" />-
<xsl:value-of select=
"format-number(../@month, '00')" />: Insert multiple and estimated extrmaxtemp value
</xsl:message>
311 <xsl:value-of select=
"text()" />
313 <xsl:when test=
"@flag = 'E'">
314 <xsl:message>WARNING:
<xsl:value-of select=
"../@year" />-
<xsl:value-of select=
"format-number(../@month, '00')" />: Insert estimated extrmaxtemp value
</xsl:message>
315 <xsl:value-of select=
"text()" />
317 <xsl:when test=
"@flag = 'I'">
318 <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>
319 <xsl:value-of select=
"text()" />
321 <xsl:when test=
"@flag = 'M'">
322 <xsl:message>WARNING:
<xsl:value-of select=
"../@year" />-
<xsl:value-of select=
"format-number(../@month, '00')" />: Insert available extrmaxtemp marked as missing
</xsl:message>
323 <xsl:value-of select=
"text()" />
325 <xsl:when test=
"@flag = 'S'">
326 <xsl:message>WARNING:
<xsl:value-of select=
"../@year" />-
<xsl:value-of select=
"format-number(../@month, '00')" />: Insert multiple extrmaxtemp value
</xsl:message>
327 <xsl:value-of select=
"text()" />
330 <xsl:value-of select=
"text()" />
335 <!-- Process extrmintemp -->
336 <xsl:template match=
"extrmintemp">
338 <xsl:when test=
"not(text())">
339 <xsl:text>null
</xsl:text>
341 <xsl:when test=
"@flag = 'B'">
342 <xsl:message>WARNING:
<xsl:value-of select=
"../@year" />-
<xsl:value-of select=
"format-number(../@month, '00')" />: Insert multiple and estimated extrmintemp value
</xsl:message>
343 <xsl:value-of select=
"text()" />
345 <xsl:when test=
"@flag = 'E'">
346 <xsl:message>WARNING:
<xsl:value-of select=
"../@year" />-
<xsl:value-of select=
"format-number(../@month, '00')" />: Insert estimated extrmintemp value
</xsl:message>
347 <xsl:value-of select=
"text()" />
349 <xsl:when test=
"@flag = 'I'">
350 <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>
351 <xsl:value-of select=
"text()" />
353 <xsl:when test=
"@flag = 'M'">
354 <xsl:message>WARNING:
<xsl:value-of select=
"../@year" />-
<xsl:value-of select=
"format-number(../@month, '00')" />: Insert available extrmintemp marked as missing
</xsl:message>
355 <xsl:value-of select=
"text()" />
357 <xsl:when test=
"@flag = 'S'">
358 <xsl:message>WARNING:
<xsl:value-of select=
"../@year" />-
<xsl:value-of select=
"format-number(../@month, '00')" />: Insert multiple extrmintemp value
</xsl:message>
359 <xsl:value-of select=
"text()" />
362 <xsl:value-of select=
"text()" />
367 <!-- Process totrain -->
368 <xsl:template match=
"totrain">
370 <xsl:when test=
"not(text())">
371 <xsl:text>null
</xsl:text>
373 <xsl:when test=
"contains(text(), '#')">
374 <xsl:message>WARNING:
<xsl:value-of select=
"../@year" />-
<xsl:value-of select=
"format-number(../@month, '00')" />: Discard totrain containing "#"
</xsl:message>
375 <xsl:text>null
</xsl:text>
377 <xsl:when test=
"@flag = 'E'">
378 <xsl:message>WARNING:
<xsl:value-of select=
"../@year" />-
<xsl:value-of select=
"format-number(../@month, '00')" />: Insert estimated totrain value
</xsl:message>
379 <xsl:value-of select=
"text()" />
381 <xsl:when test=
"@flag = 'I'">
382 <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>
383 <xsl:value-of select=
"text()" />
385 <xsl:when test=
"@flag = 'M'">
386 <xsl:message>WARNING:
<xsl:value-of select=
"../@year" />-
<xsl:value-of select=
"format-number(../@month, '00')" />: Insert available totrain marked as missing
</xsl:message>
387 <xsl:value-of select=
"text()" />
389 <xsl:when test=
"@flag = 'T'">
390 <xsl:message>WARNING:
<xsl:value-of select=
"../@year" />-
<xsl:value-of select=
"format-number(../@month, '00')" />: Insert traces only totrain value
</xsl:message>
391 <xsl:value-of select=
"text()" />
394 <xsl:value-of select=
"text()" />
399 <!-- Process totsnow -->
400 <xsl:template match=
"totsnow">
402 <xsl:when test=
"not(text())">
403 <xsl:text>null
</xsl:text>
405 <xsl:when test=
"text() < 0">
406 <xsl:message>WARNING:
<xsl:value-of select=
"../@year" />-
<xsl:value-of select=
"format-number(../@month, '00')" />: Discard negative totsnow value
</xsl:message>
407 <xsl:text>null
</xsl:text>
409 <xsl:when test=
"@flag = 'E'">
410 <xsl:message>WARNING:
<xsl:value-of select=
"../@year" />-
<xsl:value-of select=
"format-number(../@month, '00')" />: Insert estimated totsnow value
</xsl:message>
411 <xsl:value-of select=
"text()" />
413 <xsl:when test=
"@flag = 'I'">
414 <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>
415 <xsl:value-of select=
"text()" />
417 <xsl:when test=
"@flag = 'M'">
418 <xsl:message>WARNING:
<xsl:value-of select=
"../@year" />-
<xsl:value-of select=
"format-number(../@month, '00')" />: Insert available totsnow marked as missing
</xsl:message>
419 <xsl:value-of select=
"text()" />
421 <xsl:when test=
"@flag = 'T'">
422 <xsl:message>WARNING:
<xsl:value-of select=
"../@year" />-
<xsl:value-of select=
"format-number(../@month, '00')" />: Insert traces only totsnow value
</xsl:message>
423 <xsl:value-of select=
"text()" />
426 <xsl:value-of select=
"text()" />
431 <!-- Process totprecip -->
432 <xsl:template match=
"totprecip">
434 <xsl:when test=
"not(text())">
435 <xsl:text>null
</xsl:text>
437 <xsl:when test=
"contains(text(), '#')">
438 <xsl:message>WARNING:
<xsl:value-of select=
"../@year" />-
<xsl:value-of select=
"format-number(../@month, '00')" />: Discard totprecip containing "#"
</xsl:message>
439 <xsl:text>null
</xsl:text>
441 <xsl:when test=
"@flag = 'E'">
442 <xsl:message>WARNING:
<xsl:value-of select=
"../@year" />-
<xsl:value-of select=
"format-number(../@month, '00')" />: Insert estimated totprecip value
</xsl:message>
443 <xsl:value-of select=
"text()" />
445 <xsl:when test=
"@flag = 'I'">
446 <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>
447 <xsl:value-of select=
"text()" />
449 <xsl:when test=
"@flag = 'M'">
450 <xsl:message>WARNING:
<xsl:value-of select=
"../@year" />-
<xsl:value-of select=
"format-number(../@month, '00')" />: Insert available totprecip marked as missing
</xsl:message>
451 <xsl:value-of select=
"text()" />
453 <xsl:when test=
"@flag = 'T'">
454 <xsl:message>WARNING:
<xsl:value-of select=
"../@year" />-
<xsl:value-of select=
"format-number(../@month, '00')" />: Insert traces only totprecip value
</xsl:message>
455 <xsl:value-of select=
"text()" />
458 <xsl:value-of select=
"text()" />
463 <!-- Process grndsnowlastday -->
464 <xsl:template match=
"grndsnowlastday">
466 <xsl:when test=
"not(text())">
467 <xsl:text>null
</xsl:text>
469 <xsl:when test=
"@flag = 'E'">
470 <xsl:message>WARNING:
<xsl:value-of select=
"../@year" />-
<xsl:value-of select=
"format-number(../@month, '00')" />: Insert estimated grndsnowlastday value
</xsl:message>
471 <xsl:value-of select=
"text()" />
473 <xsl:when test=
"@flag = 'M'">
474 <xsl:message>WARNING:
<xsl:value-of select=
"../@year" />-
<xsl:value-of select=
"format-number(../@month, '00')" />: Insert available grndsnowlastday marked as missing
</xsl:message>
475 <xsl:value-of select=
"text()" />
477 <xsl:when test=
"@flag = 'T'">
478 <xsl:message>WARNING:
<xsl:value-of select=
"../@year" />-
<xsl:value-of select=
"format-number(../@month, '00')" />: Insert traces only grndsnowlastday value
</xsl:message>
479 <xsl:value-of select=
"text()" />
482 <xsl:value-of select=
"text()" />
487 <!-- Process dirmaxgust -->
488 <xsl:template match=
"dirmaxgust">
490 <xsl:when test=
"not(text())">
491 <xsl:text>null
</xsl:text>
493 <xsl:when test=
"@flag = 'B'">
494 <xsl:message>WARNING:
<xsl:value-of select=
"../@year" />-
<xsl:value-of select=
"format-number(../@month, '00')" />: Insert multiple and estimated dirmaxgust value
</xsl:message>
495 <xsl:value-of select=
"text()" />
497 <xsl:when test=
"@flag = 'E'">
498 <xsl:message>WARNING:
<xsl:value-of select=
"../@year" />-
<xsl:value-of select=
"format-number(../@month, '00')" />: Insert estimated dirmaxgust value
</xsl:message>
499 <xsl:value-of select=
"text()" />
501 <xsl:when test=
"@flag = 'I'">
502 <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>
503 <xsl:value-of select=
"text()" />
505 <xsl:when test=
"@flag = 'M'">
506 <xsl:message>WARNING:
<xsl:value-of select=
"../@year" />-
<xsl:value-of select=
"format-number(../@month, '00')" />: Insert available dirmaxgust marked as missing
</xsl:message>
507 <xsl:value-of select=
"text()" />
509 <xsl:when test=
"@flag = 'S'">
510 <xsl:message>WARNING:
<xsl:value-of select=
"../@year" />-
<xsl:value-of select=
"format-number(../@month, '00')" />: Insert multiple dirmaxgust value
</xsl:message>
511 <xsl:value-of select=
"text()" />
513 <xsl:when test=
"text() = '36'">
514 <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>
515 <xsl:value-of select=
"text()" />
518 <xsl:value-of select=
"text()" />
523 <!-- Process speedmaxgust -->
524 <xsl:template match=
"speedmaxgust">
526 <xsl:when test=
"not(text())">
527 <xsl:text>null
</xsl:text>
529 <xsl:when test=
"text() = '<31'">
530 <xsl:message>WARNING:
<xsl:value-of select=
"../@year" />-
<xsl:value-of select=
"format-number(../@month, '00')" />: Discard speedmaxgust with value "
<31"
</xsl:message>
531 <xsl:text>null
</xsl:text>
533 <xsl:when test=
"@flag = 'B'">
534 <xsl:message>WARNING:
<xsl:value-of select=
"../@year" />-
<xsl:value-of select=
"format-number(../@month, '00')" />: Insert multiple and estimated speedmaxgust value
</xsl:message>
535 <xsl:value-of select=
"text()" />
537 <xsl:when test=
"@flag = 'E'">
538 <xsl:message>WARNING:
<xsl:value-of select=
"../@year" />-
<xsl:value-of select=
"format-number(../@month, '00')" />: Insert estimated speedmaxgust value
</xsl:message>
539 <xsl:value-of select=
"text()" />
541 <xsl:when test=
"@flag = 'I'">
542 <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>
543 <xsl:value-of select=
"text()" />
545 <xsl:when test=
"@flag = 'M'">
546 <xsl:message>WARNING:
<xsl:value-of select=
"../@year" />-
<xsl:value-of select=
"format-number(../@month, '00')" />: Insert available speedmaxgust marked as missing
</xsl:message>
547 <xsl:value-of select=
"text()" />
549 <xsl:when test=
"@flag = 'S'">
550 <xsl:message>WARNING:
<xsl:value-of select=
"../@year" />-
<xsl:value-of select=
"format-number(../@month, '00')" />: Insert multiple speedmaxgust value
</xsl:message>
551 <xsl:value-of select=
"text()" />
554 <xsl:value-of select=
"text()" />
560 <xsl:template name=
"camel-case">
561 <xsl:param name=
"text" select=
"."/>
562 <xsl:variable name=
"uppercase">ABCDEFGHIJKLMNOPQRSTUVWXYZ
</xsl:variable>
563 <xsl:variable name=
"lowercase">abcdefghijklmnopqrstuvwxyz
</xsl:variable>
564 <xsl:variable name=
"word" select=
"substring-before(concat($text, ' '), ' ')" />
566 <xsl:value-of select=
"translate(substring($word, 1, 1), $lowercase, $uppercase)" />
567 <xsl:value-of select=
"translate(substring($word, 2), $uppercase, $lowercase)" />
569 <xsl:if test=
"contains($text, ' ')">
570 <xsl:text> </xsl:text>
571 <xsl:call-template name=
"camel-case">
572 <xsl:with-param name=
"text" select=
"substring-after($text, ' ')"/>