1 <?xml version=
"1.0" encoding=
"UTF-8"?>
3 <!-- almanac_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()" />
38 "license": "CC-BY-
4.0",
40 "en": "
</xsl:text><xsl:value-of select=
"$station-name" /><xsl:text> average and extreme data",
41 "fr": "Moyennes et extrêmes pour la station météorologique
</xsl:text><xsl:value-of select=
"$station-name" /><xsl:text>"
43 "sources
": "[https://climate.weather.gc.ca/ Environment and Climate Change Canada]
",
44 "wikicode
": "[Category:Environment and Climate Change Canada Almanac Data] [Category:Weather Data in
</xsl:text>
45 <xsl:value-of select=
"$province-name" />
68 "en": "Highest maximum temperature",
69 "fr": "Température maximale la plus élevée"
76 "en": "Lowest minimum temperature",
77 "fr": "Température minimale la plus basse"
84 "en": "Highest normal temperature",
85 "fr": "Température normale haute"
92 "en": "Lowest normal temperature",
93 "fr": "Température normale basse"
100 "en": "Mean normal temperature",
101 "fr": "Température normale moyenne"
105 "name": "extremeRainfall",
108 "en": "Greatest rainfall",
109 "fr": "Pluie maximale"
113 "name": "extremeSnowfall",
116 "en": "Greatest snowfall",
117 "fr": "Neige maximale"
121 "name": "extremePrecipitation",
124 "en": "Greatest precipitation",
125 "fr": "Précipitation maximale"
129 "name": "extremeSnowOnGround",
132 "en": "Most snow on the ground",
133 "fr": "Maximum de neige au sol"
140 "en": "Monthly frequency of precipitation",
141 "fr": "Fréquence mensuelle de précipitation"
147 <xsl:apply-templates select=
"month" />
148 <xsl:text>]}
</xsl:text>
151 <xsl:template match=
"month">
152 <!-- TODO: Check element has at least one data? -->
153 <xsl:apply-templates select=
"day">
154 <xsl:with-param name=
"month" select=
"format-number(@index, '00')" />
155 </xsl:apply-templates>
156 <xsl:if test=
"day and following-sibling::month[day]">
157 <xsl:text>,
</xsl:text>
161 <xsl:template match=
"day">
162 <xsl:param name=
"month" />
163 <xsl:param name=
"day" select=
"format-number(@index, '00')" />
165 <xsl:text>["
</xsl:text>
166 <xsl:value-of select=
"$month" />-
<xsl:value-of select=
"$day" />
167 <xsl:text>"</xsl:text>
169 <!-- Set extremeMax -->
170 <xsl:text>, </xsl:text>
171 <xsl:apply-templates select="temperature[@class = 'extremeMax']
">
172 <xsl:with-param name="date
"><xsl:value-of select="$month
" />-<xsl:value-of select="$day
" /></xsl:with-param>
173 </xsl:apply-templates>
175 <!-- Set extremeMin -->
176 <xsl:text>, </xsl:text>
177 <xsl:apply-templates select="temperature[@class = 'extremeMin']
">
178 <xsl:with-param name="date
"><xsl:value-of select="$month
" />-<xsl:value-of select="$day
" /></xsl:with-param>
179 </xsl:apply-templates>
181 <!-- Set normalMax -->
182 <xsl:text>, </xsl:text>
183 <xsl:apply-templates select="temperature[@class = 'normalMax']
">
184 <xsl:with-param name="date
"><xsl:value-of select="$month
" />-<xsl:value-of select="$day
" /></xsl:with-param>
185 </xsl:apply-templates>
187 <!-- Set normalMin -->
188 <xsl:text>, </xsl:text>
189 <xsl:apply-templates select="temperature[@class = 'normalMin']
">
190 <xsl:with-param name="date
"><xsl:value-of select="$month
" />-<xsl:value-of select="$day
" /></xsl:with-param>
191 </xsl:apply-templates>
193 <!-- Set normalMean -->
194 <xsl:text>, </xsl:text>
195 <xsl:apply-templates select="temperature[@class = 'normalMean']
">
196 <xsl:with-param name="date
"><xsl:value-of select="$month
" />-<xsl:value-of select="$day
" /></xsl:with-param>
197 </xsl:apply-templates>
199 <!-- Set extremeRainfall -->
200 <xsl:text>, </xsl:text>
201 <xsl:apply-templates select="precipitation[@class = 'extremeRainfall']
">
202 <xsl:with-param name="date
"><xsl:value-of select="$month
" />-<xsl:value-of select="$day
" /></xsl:with-param>
203 </xsl:apply-templates>
205 <!-- Set extremeSnowfall -->
206 <xsl:text>, </xsl:text>
207 <xsl:apply-templates select="precipitation[@class = 'extremeSnowfall']
">
208 <xsl:with-param name="date
"><xsl:value-of select="$month
" />-<xsl:value-of select="$day
" /></xsl:with-param>
209 </xsl:apply-templates>
211 <!-- Set extremePrecipitation -->
212 <xsl:text>, </xsl:text>
213 <xsl:apply-templates select="precipitation[@class = 'extremePrecipitation']
">
214 <xsl:with-param name="date
"><xsl:value-of select="$month
" />-<xsl:value-of select="$day
" /></xsl:with-param>
215 </xsl:apply-templates>
217 <!-- Set extremeSnowOnGround -->
218 <xsl:text>, </xsl:text>
219 <xsl:apply-templates select="precipitation[@class = 'extremeSnowOnGround']
">
220 <xsl:with-param name="date
"><xsl:value-of select="$month
" />-<xsl:value-of select="$day
" /></xsl:with-param>
221 </xsl:apply-templates>
224 <!-- WARNING: This is not daily data, it makes no sense to have it in final dataset -->
225 <xsl:text>, </xsl:text>
226 <xsl:apply-templates select="pop
" />
228 <xsl:text>]</xsl:text>
229 <xsl:if test="position() != last()
">
230 <xsl:text>, </xsl:text>
234 <xsl:template match="temperature[@class = 'extremeMax']
">
235 <xsl:param name="date
" />
238 <xsl:when test="not(text())
">
239 <xsl:text>null</xsl:text>
241 <xsl:when test="@quality = '†'
">
242 <xsl:message>WARNING: <xsl:value-of select="$date
" />: Insert not reviewed extremeMax value</xsl:message>
243 <xsl:value-of select="text()
" />
246 <xsl:value-of select="text()
" />
251 <xsl:template match="temperature[@class = 'extremeMin']
">
252 <xsl:param name="date
" />
255 <xsl:when test="not(text())
">
256 <xsl:text>null</xsl:text>
258 <xsl:when test="@quality = '†'
">
259 <xsl:message>WARNING: <xsl:value-of select="$date
" />: Insert not reviewed extremeMin value</xsl:message>
260 <xsl:value-of select="text()
" />
263 <xsl:value-of select="text()
" />
268 <xsl:template match="temperature[@class = 'normalMax']
">
269 <xsl:param name="date
" />
272 <xsl:when test="not(text())
">
273 <xsl:text>null</xsl:text>
275 <xsl:when test="@quality = '†'
">
276 <xsl:message terminate="yes
">normalMax value not reviewed</xsl:message>
279 <xsl:value-of select="text()
" />
284 <xsl:template match="temperature[@class = 'normalMin']
">
285 <xsl:param name="date
" />
288 <xsl:when test="not(text())
">
289 <xsl:text>null</xsl:text>
291 <xsl:when test="@quality = '†'
">
292 <xsl:message terminate="yes
">normalMin value not reviewed</xsl:message>
295 <xsl:value-of select="text()
" />
300 <xsl:template match="temperature[@class = 'normalMean']
">
301 <xsl:param name="date
" />
304 <xsl:when test="not(text())
">
305 <xsl:text>null</xsl:text>
307 <xsl:when test="@quality = '†'
">
308 <xsl:message terminate="yes
">normalMean value not reviewed</xsl:message>
311 <xsl:value-of select="text()
" />
316 <xsl:template match="precipitation[@class = 'extremeRainfall']
">
317 <xsl:param name="date
" />
320 <xsl:when test="not(text())
">
321 <xsl:text>null</xsl:text>
323 <xsl:when test="@quality = '†'
">
324 <xsl:message>WARNING: <xsl:value-of select="$date
" />: Insert not reviewed extremeRainfall value</xsl:message>
325 <xsl:value-of select="text()
" />
328 <xsl:value-of select="text()
" />
333 <xsl:template match="precipitation[@class = 'extremeSnowfall']
">
334 <xsl:param name="date
" />
337 <xsl:when test="not(text())
">
338 <xsl:text>null</xsl:text>
340 <xsl:when test="@quality = '†'
">
341 <xsl:message>WARNING: <xsl:value-of select="$date
" />: Insert not reviewed extremeSnowfall value</xsl:message>
342 <xsl:value-of select="text()
" />
345 <xsl:value-of select="text()
" />
350 <xsl:template match="precipitation[@class = 'extremePrecipitation']
">
351 <xsl:param name="date
" />
354 <xsl:when test="not(text())
">
355 <xsl:text>null</xsl:text>
357 <xsl:when test="@quality = '†'
">
358 <xsl:message>WARNING: <xsl:value-of select="$date
" />: Insert not reviewed extremePrecipitation value</xsl:message>
359 <xsl:value-of select="text()
" />
362 <xsl:value-of select="text()
" />
367 <xsl:template match="precipitation[@class = 'extremeSnowOnGround']
">
368 <xsl:param name="date
" />
371 <xsl:when test="not(text())
">
372 <xsl:text>null</xsl:text>
374 <xsl:when test="contains(text(), '#')
">
375 <xsl:message>WARNING: <xsl:value-of select="$date
" />: Discard extremeSnowOnGround containing "#"
</xsl:message>
376 <xsl:text>null
</xsl:text>
378 <xsl:when test=
"@quality = '†'">
379 <xsl:message>WARNING:
<xsl:value-of select=
"$date" />: Insert not reviewed extremeSnowOnGround value
</xsl:message>
380 <xsl:value-of select=
"text()" />
383 <xsl:value-of select=
"text()" />
388 <xsl:template match=
"pop">
389 <xsl:param name=
"date" />
392 <xsl:when test=
"not(text())">
393 <xsl:text>null
</xsl:text>
395 <xsl:when test=
"@quality = '†'">
396 <xsl:message terminate=
"yes">pop value not reviewed
</xsl:message>
399 <xsl:value-of select=
"text()" />
405 <xsl:template name=
"camel-case">
406 <xsl:param name=
"text" select=
"."/>
407 <xsl:variable name=
"uppercase">ABCDEFGHIJKLMNOPQRSTUVWXYZ
</xsl:variable>
408 <xsl:variable name=
"lowercase">abcdefghijklmnopqrstuvwxyz
</xsl:variable>
409 <xsl:variable name=
"word" select=
"substring-before(concat($text, ' '), ' ')" />
411 <xsl:value-of select=
"translate(substring($word, 1, 1), $lowercase, $uppercase)" />
412 <xsl:value-of select=
"translate(substring($word, 2), $uppercase, $lowercase)" />
414 <xsl:if test=
"contains($text, ' ')">
415 <xsl:text> </xsl:text>
416 <xsl:call-template name=
"camel-case">
417 <xsl:with-param name=
"text" select=
"substring-after($text, ' ')"/>