Ticket #1844: gml2gfs.xsl

File gml2gfs.xsl, 9.4 kB (added by nf, 1 year ago)

XSL to generate a GFS from a GML, working around this bug

Line 
1 <?xml version="1.0" encoding="ISO-8859-1"?>
2 <xsl:transform version="1.0"
3 xmlns:tc="http://www.bom.gov.au/dtd/tc"
4 xmlns:gml="http://www.opengis.net/gml"
5 xmlns:exsl="http://exslt.org/common"
6 extension-element-prefixes="exsl"
7 xmlns:maximum-pick-bigger="f:maximum-pick-bigger"
8 xmlns:maximum-own-compare="f:maximum-own-compare"
9 xmlns:maximum-len-compare="f:maximum-len-compare"
10 xmlns:maximum-type-compare="f:maximum-type-compare"
11 exclude-result-prefixes="xsl maximum-own-compare maximum-pick-bigger"
12 xmlns:fn="http://www.w3.org/2005/02/xpath-functions"
13 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
14 <xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
15
16 <xsl:template match="/featureCollection">
17 <GMLFeatureClassList>
18     <GMLFeatureClass>
19         <Name>GML2GFS</Name>
20         <ElementPath>GML2GFS</ElementPath>
21         <DatasetSpecificInfo>
22             <FeatureCount>
23                 <xsl:value-of select="count(gml:featureMember)"/>
24             </FeatureCount>
25             <ExtentXMin>
26                 <xsl:value-of select="gml:boundedBy/gml:Box/gml:coord[1]/gml:X"/>
27             </ExtentXMin>
28             <ExtentXMax>
29                 <xsl:value-of select="gml:boundedBy/gml:Box/gml:coord[2]/gml:X"/>
30             </ExtentXMax>
31             <ExtentYMin>
32                 <xsl:value-of select="gml:boundedBy/gml:Box/gml:coord[1]/gml:Y"/>
33             </ExtentYMin>
34             <ExtentYMax>
35                 <xsl:value-of select="gml:boundedBy/gml:Box/gml:coord[2]/gml:Y"/>
36             </ExtentYMax>
37         </DatasetSpecificInfo>
38         <xsl:for-each select="gml:featureMember[last()]//*[geometryProperty]/*">
39           <xsl:if test="name() != 'geometryProperty'">
40             <PropertyDefn>
41                 <xsl:variable name="name" select="name()"/>
42                 <Name>
43                     <xsl:value-of select="$name"/>
44                 </Name>
45                 <ElementPath>
46                     <xsl:value-of select="$name"/>
47                 </ElementPath>
48                     <xsl:variable name="worstTypeValue">
49                         <xsl:call-template name="maximumType">
50                             <xsl:with-param name="pList" select="/featureCollection/gml:featureMember//*[name() = $name and name() != 'geometryProperty']"/>
51                         </xsl:call-template>
52                     </xsl:variable>
53                     <xsl:variable name="worstType">
54                         <xsl:choose>
55                           <xsl:when test="round(concat(substring-before($worstTypeValue, '.'),substring-after($worstTypeValue, '.')))">Float</xsl:when>
56                           <xsl:when test="string(round($worstTypeValue)) = 'NaN'">String</xsl:when>
57                           <xsl:otherwise>Integer</xsl:otherwise>
58                         </xsl:choose>
59                     </xsl:variable>
60                 <Type>
61                     <xsl:value-of select="$worstType"/>
62                 </Type>
63                 <xsl:if test="$worstType = 'String'">
64                   <Width>
65                     <xsl:variable name="longestString">
66                         <xsl:call-template name="maximumLength">
67                             <xsl:with-param name="pList" select="/featureCollection/gml:featureMember//*[name() = $name and name() != 'geometryProperty']"/>
68                         </xsl:call-template>
69                     </xsl:variable>
70                     <xsl:value-of select="string-length($longestString)"/>
71                   </Width>
72                 </xsl:if>
73             </PropertyDefn>
74           </xsl:if>
75         </xsl:for-each>
76     </GMLFeatureClass>
77 </GMLFeatureClassList>
78 </xsl:template>
79
80 <xsl:template name="foldl">
81 <xsl:param name="pFunc" select="/.."/>
82   <xsl:param name="pA0"/>
83   <xsl:param name="pList" select="/.."/>
84
85   <xsl:choose>
86      <xsl:when test="not($pList)">
87         <xsl:copy-of select="$pA0"/>
88      </xsl:when>
89      <xsl:otherwise>
90        <xsl:variable name="vFunResult">
91           <xsl:apply-templates select="$pFunc[1]">
92             <xsl:with-param name="arg0" select="$pFunc[position() > 1]"/>
93             <xsl:with-param name="arg1" select="$pA0"/>
94             <xsl:with-param name="arg2" select="$pList[1]"/>
95           </xsl:apply-templates>
96        </xsl:variable>
97
98        <xsl:call-template name="foldl">
99           <xsl:with-param name="pFunc" select="$pFunc"/>
100           <xsl:with-param name="pList" select="$pList[position() > 1]"/>
101           <xsl:with-param name="pA0" select="$vFunResult"/>
102
103        </xsl:call-template>
104      </xsl:otherwise>
105   </xsl:choose>
106
107 </xsl:template>
108
109    <maximum-pick-bigger:maximum-pick-bigger/>
110    <maximum-own-compare:maximum-own-compare/>
111    <maximum-len-compare:maximum-len-compare/>
112    <maximum-type-compare:maximum-type-compare/>
113
114     <xsl:template name="maximumType">
115       <xsl:param name="pList" select="/.."/>
116       <xsl:param name="pCMPFun" select="/.."/>
117
118       <xsl:variable name="vdfCMPFun"
119            select="document('')/*/maximum-type-compare:*"/>
120       <xsl:variable name="vFoldFun"
121            select="document('')/*/maximum-pick-bigger:*[1]"/>
122    
123       <xsl:if test="$pList">
124          <xsl:variable name="vCMPFun" select="$pCMPFun |
125 $vdfCMPFun[not($pCMPFun)]"/>
126          <xsl:variable name="vFuncList">
127             <xsl:copy-of select="$vFoldFun"/> <!-- Pick Bigger -->
128             <xsl:copy-of select="$vCMPFun"/>  <!-- Compare -->
129          </xsl:variable>
130
131          <xsl:call-template name="foldl">
132             <xsl:with-param name="pFunc" select="exsl:node-set($vFuncList)/*"/>
133             <xsl:with-param name="pList" select="$pList"/>
134             <xsl:with-param name="pA0" select="$pList[1]"/>
135          </xsl:call-template>
136       </xsl:if>
137     </xsl:template>
138
139     <xsl:template name="maximumLength">
140       <xsl:param name="pList" select="/.."/>
141       <xsl:param name="pCMPFun" select="/.."/>
142
143       <xsl:variable name="vdfCMPFun"
144            select="document('')/*/maximum-len-compare:*"/>
145       <xsl:variable name="vFoldFun"
146            select="document('')/*/maximum-pick-bigger:*[1]"/>
147    
148       <xsl:if test="$pList">
149          <xsl:variable name="vCMPFun" select="$pCMPFun |
150 $vdfCMPFun[not($pCMPFun)]"/>
151          <xsl:variable name="vFuncList">
152             <xsl:copy-of select="$vFoldFun"/> <!-- Pick Bigger -->
153             <xsl:copy-of select="$vCMPFun"/>  <!-- Compare -->
154          </xsl:variable>
155
156          <xsl:call-template name="foldl">
157             <xsl:with-param name="pFunc" select="exsl:node-set($vFuncList)/*"/>
158             <xsl:with-param name="pList" select="$pList"/>
159             <xsl:with-param name="pA0" select="$pList[1]"/>
160          </xsl:call-template>
161       </xsl:if>
162     </xsl:template>
163
164
165     <xsl:template name="maximum">
166       <xsl:param name="pList" select="/.."/>
167       <xsl:param name="pCMPFun" select="/.."/>
168
169       <xsl:variable name="vdfCMPFun"
170            select="document('')/*/maximum-own-compare:*[name='isGreaterDefault']"/>
171       <xsl:variable name="vFoldFun"
172            select="document('')/*/maximum-pick-bigger:*[1]"/>
173    
174       <xsl:if test="$pList">
175          <xsl:variable name="vCMPFun" select="$pCMPFun |
176 $vdfCMPFun[not($pCMPFun)]"/>
177          <xsl:variable name="vFuncList">
178             <xsl:copy-of select="$vFoldFun"/> <!-- Pick Bigger -->
179             <xsl:copy-of select="$vCMPFun"/>  <!-- Compare -->
180          </xsl:variable>
181
182          <xsl:call-template name="foldl">
183             <xsl:with-param name="pFunc" select="exsl:node-set($vFuncList)/*"/>
184             <xsl:with-param name="pList" select="$pList"/>
185             <xsl:with-param name="pA0" select="$pList[1]"/>
186          </xsl:call-template>
187       </xsl:if>
188     </xsl:template>
189
190
191
192
193     <xsl:template name="pickBigger" match="maximum-pick-bigger:*">
194          <xsl:param name="arg0"/>
195          <xsl:param name="arg1"/>
196          <xsl:param name="arg2"/>
197
198          <xsl:variable name="vIsGreater">
199            <xsl:apply-templates select="$arg0">
200              <xsl:with-param name="arg1" select="$arg1"/>
201              <xsl:with-param name="arg2" select="$arg2"/>
202            </xsl:apply-templates>
203          </xsl:variable>
204          <xsl:choose>
205            <xsl:when test="$vIsGreater = 1">
206              <xsl:copy-of select="$arg1"/>
207            </xsl:when>
208            <xsl:otherwise>
209              <xsl:copy-of select="$arg2"/>
210            </xsl:otherwise>
211          </xsl:choose>
212     </xsl:template>
213
214     <xsl:template name="isGreaterType" match="maximum-type-compare:*">
215          <xsl:param name="arg1"/>
216          <xsl:param name="arg2"/>
217
218          <xsl:choose>
219           <!--  If arg1 is a float, '1' -->
220           <xsl:when test="round(concat(substring-before($arg1, '.'),substring-after($arg1, '.')))">1</xsl:when>
221           <!--  If arg1 is a string, '0' -->
222           <xsl:when test="string(round($arg1)) = 'NaN'">0</xsl:when>
223           <!--  If arg2 is a float, '0' -->
224           <xsl:when test="round(concat(substring-before($arg2, '.'),substring-after($arg1, '.')))">0</xsl:when>
225           <!-- otherwise, 1 -->
226           <xsl:otherwise>1</xsl:otherwise>
227          </xsl:choose>
228     </xsl:template>
229
230     <xsl:template name="isGreaterDefault" match="maximum-own-compare:*">
231          <xsl:param name="arg1"/>
232          <xsl:param name="arg2"/>
233
234          <xsl:choose>
235           <xsl:when test="$arg1 > $arg2">1</xsl:when>
236           <xsl:otherwise>0</xsl:otherwise>
237          </xsl:choose>
238     </xsl:template>
239
240
241     <xsl:template name="isGreaterLength" match="maximum-len-compare:*">
242          <xsl:param name="arg1"/>
243          <xsl:param name="arg2"/>
244
245          <xsl:choose>
246           <xsl:when test="string-length($arg1) > string-length($arg2)">1</xsl:when>
247           <xsl:otherwise>0</xsl:otherwise>
248          </xsl:choose>
249     </xsl:template>
250
251
252 </xsl:transform>