]>
Wikimedia Canada | Git repositories - eccc_to_commons.git/blob - eccc_merger_almanach.xslt
1 <?xml version =
"1.0" encoding =
"UTF-8" ?>
3 <!-- eccc_merger.xslt - Merge XML historical data as provided by
4 Environment and Climate Change Canada
5 Copyright (C) 2020 Pierre Choffet
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 Rounding is always done one digit after decimal point.
23 Output data is calculated as such:
24 temperature.extremeMax : Greatest of all values
25 temperature.extremeMin : Lowest of all values
26 temperature.normalMax : Greatest of all values
27 temperature.normalMin : Lowest of all values
28 temperature.normalMean : Weighted mean of all values
29 precipitation.extremeRainfall : Greatest of all values
30 precipitation.extremeSnowfall : Greatest of all values
31 precipitation.extremePrecipitation: Greatest of all values
32 precipitation.extremeSnowOnGround : Greatest of all values
33 pop : Weighted mean of all values
36 <xsl:stylesheet version =
"1.0" xmlns:
xsl =
"http://www.w3.org/1999/XSL/Transform"
37 xmlns:
xsi =
"http://www.w3.org/2001/XMLSchema-instance"
38 exclude-result-prefixes =
"xsi" >
40 <xsl:output method =
"xml" encoding =
"utf-8" />
42 <xsl:variable name =
"input-root" select =
"/" />
43 <xsl:variable name =
"merge-doc" select =
"document($merge-path)" />
46 <xsl:template match =
"@*|node()" >
48 <xsl:apply-templates select =
"@*|node()" />
52 <xsl:template match =
"/climatedata" >
54 <!-- Upon first merge, import missing metadata elements -->
55 <xsl:if test =
"not(lang)" >
56 <xsl:apply-templates select =
"$merge-doc/climatedata/lang" />
58 <xsl:if test =
"not(stationinformation)" >
59 <xsl:apply-templates select =
"$merge-doc/climatedata/stationinformation" />
62 <xsl:apply-templates select =
"@*|node()" />
66 <xsl:template match =
"month" >
68 <xsl:apply-templates select =
"@index" />
70 <!-- ECCC data may not contain all days element, so we're counting by ourserves -->
71 <xsl:call-template name =
"loop-day" >
72 <xsl:with-param name =
"day" select =
"1" />
77 <xsl:template match =
"day" >
79 <xsl:attribute name =
"index" >
80 <xsl:value-of select =
"@index" />
83 <xsl:apply-templates match =
"node()" />
87 <xsl:template match =
"temperature[@class = 'extremeMax']" >
88 <xsl:variable name =
"month" select =
"../../@index" />
89 <xsl:variable name =
"day" select =
"../@index" />
90 <xsl:variable name =
"input-extreme-max" select =
"$input-root/climatedata/month[@index = $month]/day[@index = $day]/temperature[@class = 'extremeMax']" />
91 <xsl:variable name =
"merge-extreme-max" select =
"$merge-doc/climatedata/month[@index = $month]/day[@index = $day]/temperature[@class = 'extremeMax']" />
94 <xsl:when test =
"$input-extreme-max and (not($merge-extreme-max) or $input-extreme-max/text() >= $merge-extreme-max/text())" >
96 <xsl:apply-templates select =
"$input-extreme-max/@*" />
97 <xsl:apply-templates select =
"$input-extreme-max/node()" />
102 <xsl:apply-templates select =
"$merge-extreme-max/@*" />
103 <xsl:apply-templates select =
"$merge-extreme-max/node()" />
109 <xsl:template match =
"temperature[@class = 'extremeMin']" >
110 <xsl:variable name =
"month" select =
"../../@index" />
111 <xsl:variable name =
"day" select =
"../@index" />
112 <xsl:variable name =
"input-extreme-min" select =
"$input-root/climatedata/month[@index = $month]/day[@index = $day]/temperature[@class = 'extremeMin']" />
113 <xsl:variable name =
"merge-extreme-min" select =
"$merge-doc/climatedata/month[@index = $month]/day[@index = $day]/temperature[@class = 'extremeMin']" />
116 <xsl:when test =
"$input-extreme-min and (not($merge-extreme-min) or $input-extreme-min/text() <= merge-extreme-min/text())" >
118 <xsl:apply-templates select =
"$input-extreme-min/@*" />
119 <xsl:apply-templates select =
"$input-extreme-min/node()" />
124 <xsl:apply-templates select =
"$merge-extreme-min/@*" />
125 <xsl:apply-templates select =
"$merge-extreme-min/node()" />
131 <xsl:template match =
"temperature[@class = 'normalMax']" >
132 <xsl:variable name =
"month" select =
"../../@index" />
133 <xsl:variable name =
"day" select =
"../@index" />
134 <xsl:variable name =
"input-normal-max" select =
"$input-root/climatedata/month[@index = $month]/day[@index = $day]/temperature[@class = 'normalMax']" />
135 <xsl:variable name =
"merge-normal-max" select =
"$merge-doc/climatedata/month[@index = $month]/day[@index = $day]/temperature[@class = 'normalMax']" />
138 <xsl:when test =
"$input-normal-max and (not($merge-normal-max) or $input-normal-max/text() >= $merge-normal-max/text())" >
140 <xsl:apply-templates select =
"$input-normal-max/@*" />
141 <xsl:apply-templates select =
"$input-normal-max/node()" />
146 <xsl:apply-templates select =
"$merge-normal-max/@*" />
147 <xsl:apply-templates select =
"$merge-normal-max/node()" />
153 <xsl:template match =
"temperature[@class = 'normalMin']" >
154 <xsl:variable name =
"month" select =
"../../@index" />
155 <xsl:variable name =
"day" select =
"../@index" />
156 <xsl:variable name =
"input-normal-min" select =
"$input-root/climatedata/month[@index = $month]/day[@index = $day]/temperature[@class = 'normalMin']" />
157 <xsl:variable name =
"merge-normal-min" select =
"$merge-doc/climatedata/month[@index = $month]/day[@index = $day]/temperature[@class = 'normalMin']" />
160 <xsl:when test =
"$input-normal-min and (not($merge-normal-min) or $input-normal-min/text() <= $merge-normal-min/text())" >
162 <xsl:apply-templates select =
"$input-normal-min/@*" />
163 <xsl:apply-templates select =
"$input-normal-min/node()" />
168 <xsl:apply-templates select =
"$merge-normal-min/@*" />
169 <xsl:apply-templates select =
"$merge-normal-min/node()" />
175 <xsl:template match =
"temperature[@class = 'normalMean']" >
176 <xsl:variable name =
"month" select =
"../../@index" />
177 <xsl:variable name =
"day" select =
"../@index" />
178 <xsl:variable name =
"input-normal-mean" select =
"$input-root/climatedata/month[@index = $month]/day[@index = $day]/temperature[@class = 'normalMean']" />
179 <xsl:variable name =
"merge-normal-mean" select =
"$merge-doc/climatedata/month[@index = $month]/day[@index = $day]/temperature[@class = 'normalMean']" />
182 <xsl:when test =
"$input-normal-mean and $input-normal-mean/text() != '' and $merge-normal-mean and $merge-normal-mean/text() != ''" >
184 <xsl:apply-templates select =
"$input-normal-mean/@*" />
185 <xsl:attribute name =
"values-count" ><xsl:value-of select =
"$input-normal-mean/@values-count + 1" /></xsl:attribute>
186 <xsl:value-of select =
"format-number(number($input-normal-mean/text() * $input-normal-mean/@values-count + $merge-normal-mean/text()) div number($input-normal-mean/@values-count + 1), '0.0')" />
189 <xsl:when test =
"$input-normal-mean and (not($merge-normal-mean) or $merge-normal-mean/text() = '')" >
191 <xsl:apply-templates select =
"$input-normal-mean/@*" />
192 <xsl:apply-templates select =
"$input-normal-mean/node()" />
195 <xsl:when test =
"not($input-normal-mean) and $merge-normal-mean and $merge-normal-mean/text() != ''" >
197 <xsl:apply-templates select =
"$merge-normal-mean/@*" />
198 <xsl:attribute name =
"values-count" > 1 </xsl:attribute>
199 <xsl:apply-templates select =
"$merge-normal-mean/node()" />
205 <xsl:template match =
"precipitation[@class = 'extremeRainfall']" >
206 <xsl:variable name =
"month" select =
"../../@index" />
207 <xsl:variable name =
"day" select =
"../@index" />
208 <xsl:variable name =
"input-precipitation-rainfall" select =
"$input-root/climatedata/month[@index = $month]/day[@index = $day]/precipitation[@class = 'extremeRainfall']" />
209 <xsl:variable name =
"merge-precipitation-rainfall" select =
"$merge-doc/climatedata/month[@index = $month]/day[@index = $day]/precipitation[@class = 'extremeRainfall']" />
212 <xsl:when test =
"$input-precipitation-rainfall and (not($merge-precipitation-rainfall) or $input-precipitation-rainfall/text() >= $merge-precipitation-rainfall/text())" >
214 <xsl:apply-templates select =
"$input-precipitation-rainfall/@*" />
215 <xsl:apply-templates select =
"$input-precipitation-rainfall/node()" />
220 <xsl:apply-templates select =
"$merge-precipitation-rainfall/@*" />
221 <xsl:apply-templates select =
"$merge-precipitation-rainfall/node()" />
227 <xsl:template match =
"precipitation[@class = 'extremeSnowfall']" >
228 <xsl:variable name =
"month" select =
"../../@index" />
229 <xsl:variable name =
"day" select =
"../@index" />
230 <xsl:variable name =
"input-precipitation-snowfall" select =
"$input-root/climatedata/month[@index = $month]/day[@index = $day]/precipitation[@class = 'extremeSnowfall']" />
231 <xsl:variable name =
"merge-precipitation-snowfall" select =
"$merge-doc/climatedata/month[@index = $month]/day[@index = $day]/precipitation[@class = 'extremeSnowfall']" />
234 <xsl:when test =
"$input-precipitation-snowfall and (not($merge-precipitation-snowfall) or $input-precipitation-snowfall/text() >= $merge-precipitation-snowfall/text())" >
236 <xsl:apply-templates select =
"$input-precipitation-snowfall/@*" />
237 <xsl:apply-templates select =
"$input-precipitation-snowfall/node()" />
242 <xsl:apply-templates select =
"$merge-precipitation-snowfall/@*" />
243 <xsl:apply-templates select =
"$merge-precipitation-snowfall/node()" />
249 <xsl:template match =
"precipitation[@class = 'extremePrecipitation']" >
250 <xsl:variable name =
"month" select =
"../../@index" />
251 <xsl:variable name =
"day" select =
"../@index" />
252 <xsl:variable name =
"input-precipitation-extreme" select =
"$input-root/climatedata/month[@index = $month]/day[@index = $day]/precipitation[@class = 'extremePrecipitation']" />
253 <xsl:variable name =
"merge-precipitation-extreme" select =
"$merge-doc/climatedata/month[@index = $month]/day[@index = $day]/precipitation[@class = 'extremePrecipitation']" />
256 <xsl:when test =
"$input-precipitation-extreme and (not($merge-precipitation-extreme) or $input-precipitation-extreme/text() >= $merge-precipitation-extreme/text())" >
258 <xsl:apply-templates select =
"$input-precipitation-extreme/@*" />
259 <xsl:apply-templates select =
"$input-precipitation-extreme/node()" />
264 <xsl:apply-templates select =
"$merge-precipitation-extreme/@*" />
265 <xsl:apply-templates select =
"$merge-precipitation-extreme/node()" />
271 <xsl:template match =
"precipitation[@class = 'extremeSnowOnGround']" >
272 <xsl:variable name =
"month" select =
"../../@index" />
273 <xsl:variable name =
"day" select =
"../@index" />
274 <xsl:variable name =
"input-precipitation-snow-ground" select =
"$input-root/climatedata/month[@index = $month]/day[@index = $day]/precipitation[@class = 'extremeSnowOnGround']" />
275 <xsl:variable name =
"merge-precipitation-snow-ground" select =
"$merge-doc/climatedata/month[@index = $month]/day[@index = $day]/precipitation[@class = 'extremeSnowOnGround']" />
278 <xsl:when test =
"$input-precipitation-snow-ground and (not($merge-precipitation-snow-ground) or $input-precipitation-snow-ground/text() >= $merge-precipitation-snow-ground/text())" >
280 <xsl:apply-templates select =
"$input-precipitation-snow-ground/@*" />
281 <xsl:apply-templates select =
"$input-precipitation-snow-ground/node()" />
286 <xsl:apply-templates select =
"$merge-precipitation-snow-ground/@*" />
287 <xsl:apply-templates select =
"$merge-precipitation-snow-ground/node()" />
293 <xsl:template match =
"pop" >
294 <xsl:variable name =
"month" select =
"../../@index" />
295 <xsl:variable name =
"day" select =
"../@index" />
296 <xsl:variable name =
"input-pop" select =
"$input-root/climatedata/month[@index = $month]/day[@index = $day]/pop" />
297 <xsl:variable name =
"merge-pop" select =
"$merge-doc/climatedata/month[@index = $month]/day[@index = $day]/pop" />
300 <xsl:when test =
"$input-pop and $input-pop/text() != '' and $merge-pop and $merge-pop/text() != ''" >
302 <xsl:apply-templates select =
"$input-pop/@*" />
303 <xsl:attribute name =
"values-count" ><xsl:value-of select =
"$input-pop/@values-count + 1" /></xsl:attribute>
304 <xsl:value-of select =
"format-number(number($input-pop/text() * $input-pop/@values-count + $merge-pop/text()) div number($input-pop/@values-count + 1), '0.0')" />
307 <xsl:when test =
"$input-pop and (not($merge-pop) or $merge-pop/text() = '')" >
309 <xsl:apply-templates select =
"$input-pop/@*" />
310 <xsl:apply-templates select =
"$input-pop/node()" />
313 <xsl:when test =
"not($input-pop) and $merge-pop and $merge-pop/text() != ''" >
315 <xsl:apply-templates select =
"$merge-pop/@*" />
316 <xsl:attribute name =
"values-count" > 1 </xsl:attribute>
317 <xsl:apply-templates select =
"$merge-pop/node()" />
323 <xsl:template name =
"loop-day" >
324 <xsl:param name =
"day" />
326 <xsl:variable name =
"input-day" select =
"$input-root/climatedata/month[@index = current()/@index]/day[@index = $day]" />
327 <xsl:variable name =
"merge-day" select =
"$merge-doc/climatedata/month[@index = current()/@index]/day[@index = $day]" />
330 <xsl:when test =
"$input-day" >
331 <xsl:apply-templates select =
"$input-day" />
333 <xsl:when test =
"$merge-day" >
334 <xsl:apply-templates select =
"$merge-day" />
338 <xsl:if test =
"$day < 31" >
339 <xsl:call-template name =
"loop-day" >
340 <xsl:with-param name =
"day" select =
"$day + 1" />
345 <!-- Almanach files contain no flags -->
346 <xsl:template match =
"legend" />
348 <!-- Remove quality indicator -->
349 <xsl:template match =
"@quality" />