1 | <?xml version="1.0" encoding="ISO-8859-1"?> |
---|
2 | |
---|
3 | <xsl:stylesheet version="3.0" |
---|
4 | xmlns:xsl ="http://www.w3.org/1999/XSL/Transform" |
---|
5 | xmlns:xs ="http://www.w3.org/2001/XMLSchema" |
---|
6 | xmlns:ibis="http://www.ibisph.org" |
---|
7 | |
---|
8 | exclude-result-prefixes="ibis xs xsl" |
---|
9 | > |
---|
10 | |
---|
11 | <ibis:doc> |
---|
12 | <name>xml/Interactive</name> |
---|
13 | <summary>Provides XML elements used by Kendo and Leaflet XSLT</summary> |
---|
14 | <description> |
---|
15 | Provides XSLT templates used to produce RECORD_DIMENSION_FIELD, |
---|
16 | RECORD_ANCILLARY_VALUE_FIELD, filter down IP View DATASET_RECORDs, |
---|
17 | and misc calls like unique, sorted, csvDimensionsTitleList. |
---|
18 | |
---|
19 | These structures are used by the JSON processing XSLT code which is |
---|
20 | then passed to the specific Kendo and Leaflet js code. These templates |
---|
21 | could have been named "DataViz" but this would be confusing when trying |
---|
22 | to maintain. |
---|
23 | |
---|
24 | The IP view or QM result page templates define the containers and |
---|
25 | control how structures and script as to be built and applied. The |
---|
26 | way this works is that the IP or QM XSLT page code get these |
---|
27 | Interactive XML structures and then pass them to more specific JSON |
---|
28 | producing XSLT templates which localize processing of those generic |
---|
29 | structs into JSON. The JSON structs are then passed to the general |
---|
30 | DataViz script templates. |
---|
31 | </description> |
---|
32 | </ibis:doc> |
---|
33 | |
---|
34 | |
---|
35 | <xsl:template name="Interactive.recordDimensionFields" |
---|
36 | ibis:doc="Creates the following struct for series, cat, and const: |
---|
37 | |
---|
38 | RECORD_DIMENSION_FIELD |
---|
39 | NAME - used for the data array/datasource fieldname |
---|
40 | TITLE - used for kendo chart series and cat title. |
---|
41 | DIMENSION_USAGE - series, category, constant |
---|
42 | DIMENSION_NAMES |
---|
43 | DIMENSION_NAME |
---|
44 | DIMENSION_VALUES_COUNT - number of dimension values to determine use. |
---|
45 | if count = 1 or 0 then don't have to do any special |
---|
46 | constant or group handling. |
---|
47 | |
---|
48 | This struct is then passed into the Interactive.indicatorViewDatasetRecords |
---|
49 | (QM dataset records are ready to go) to filter dataset records according |
---|
50 | to usage and dimensions. |
---|
51 | recordDimensionFields |
---|
52 | " |
---|
53 | > |
---|
54 | <xsl:param name="dimensions"/> |
---|
55 | <xsl:param name="dimensionUsages"/> |
---|
56 | |
---|
57 | <xsl:call-template name="Interactive.recordDimensionField"> |
---|
58 | <xsl:with-param name="usage" select="'series'"/> |
---|
59 | <xsl:with-param name="fieldName" select="'Series'"/> |
---|
60 | <xsl:with-param name="dimensions" select="$dimensions"/> |
---|
61 | <xsl:with-param name="dimensionUsages" select="$dimensionUsages"/> |
---|
62 | </xsl:call-template> |
---|
63 | <xsl:call-template name="Interactive.recordDimensionField"> |
---|
64 | <xsl:with-param name="usage" select="'category'"/> |
---|
65 | <xsl:with-param name="fieldName" select="'Category'"/> |
---|
66 | <xsl:with-param name="dimensions" select="$dimensions"/> |
---|
67 | <xsl:with-param name="dimensionUsages" select="$dimensionUsages"/> |
---|
68 | </xsl:call-template> |
---|
69 | <xsl:call-template name="Interactive.recordDimensionField"> |
---|
70 | <xsl:with-param name="usage" select="'constant'"/> |
---|
71 | <xsl:with-param name="fieldName" select="'Constant'"/> |
---|
72 | <xsl:with-param name="dimensions" select="$dimensions"/> |
---|
73 | <xsl:with-param name="dimensionUsages" select="$dimensionUsages"/> |
---|
74 | </xsl:call-template> |
---|
75 | </xsl:template> |
---|
76 | |
---|
77 | <xsl:template name="Interactive.recordDimensionField"> |
---|
78 | <xsl:param name="usage"/> |
---|
79 | <xsl:param name="fieldName"/> |
---|
80 | <xsl:param name="dimensions"/> |
---|
81 | <xsl:param name="dimensionUsages"/> |
---|
82 | |
---|
83 | <RECORD_DIMENSION_FIELD> |
---|
84 | <NAME><xsl:value-of select="$fieldName"/></NAME> |
---|
85 | <TITLE> |
---|
86 | <xsl:call-template name="Interactive.csvDimensionsTitleList"> |
---|
87 | <xsl:with-param name="dimensions" select="$dimensions//DIMENSION |
---|
88 | [NAME = $dimensionUsages//DIMENSION_USAGE[USAGE=$usage]/NAME]" |
---|
89 | /> |
---|
90 | </xsl:call-template> |
---|
91 | </TITLE> |
---|
92 | <DIMENSION_USAGE><xsl:value-of select="$usage"/></DIMENSION_USAGE> |
---|
93 | <DIMENSION_NAMES> |
---|
94 | <xsl:for-each select="$dimensionUsages//DIMENSION_USAGE[USAGE=$usage]"> |
---|
95 | <DIMENSION_NAME><xsl:value-of select="NAME"/></DIMENSION_NAME> |
---|
96 | </xsl:for-each> |
---|
97 | </DIMENSION_NAMES> |
---|
98 | <DIMENSION_VALUES_COUNT><xsl:value-of select="count($dimensionUsages//DIMENSION_USAGE[USAGE=$usage]/VALUES/VALUE)"/></DIMENSION_VALUES_COUNT> |
---|
99 | </RECORD_DIMENSION_FIELD> |
---|
100 | </xsl:template> |
---|
101 | |
---|
102 | |
---|
103 | <xsl:template name="Interactive.mapRecordDimensionFilters" |
---|
104 | ibis:doc="Creates the map dimension filter XML struct that the |
---|
105 | LeafletMap.xslt uses to create the map data record json dim filter. |
---|
106 | Struct returns 1-3 RECORD_DIMENSION_FILTER structs. |
---|
107 | " |
---|
108 | > |
---|
109 | <xsl:param name="geoDimensionName"/> |
---|
110 | <xsl:param name="dimensions"/> |
---|
111 | <xsl:param name="dimensionUsages" ibis:doc=" |
---|
112 | DIMENSION_USAGE |
---|
113 | USAGE category/series/constant/ |
---|
114 | NAME GeoCnty - dimension name |
---|
115 | VALUES |
---|
116 | VALUE dimension value SORT_ORDER |
---|
117 | " |
---|
118 | /> |
---|
119 | <xsl:param name="recordDimensionFields" ibis:doc="` |
---|
120 | generic, internal ser/cat/const struct: |
---|
121 | RECORD_DIMENSION_FIELD |
---|
122 | DIMENSION_USAGE category/series/constant - differs from NAME in NOT camel case and matches the DIMENSION_USAGE/NAME |
---|
123 | NAME Category/Series/Constant - differs from usage in that it is camel case via the XSLT code when creating this struct/NAME |
---|
124 | TITLE |
---|
125 | DIMENSION_NAMES |
---|
126 | DIMENSION_NAME GeoCnty/DIMENSION_NAME |
---|
127 | DIMENSION_VALUES_COUNT 3 - convienence value |
---|
128 | " |
---|
129 | /> |
---|
130 | |
---|
131 | <xsl:param name="geoDimensionUsage" select="$dimensionUsages/DIMENSION_USAGE[NAME = $geoDimensionName]"/> |
---|
132 | <xsl:param name="periodDimensionUsage" select="$dimensionUsages/DIMENSION_USAGE[NAME = $dimensions/DIMENSION[exists(PERIOD_FLAG)]/NAME][1]"/> |
---|
133 | |
---|
134 | <xsl:param name="otherDimensionUsage" select="$dimensionUsages/DIMENSION_USAGE[USAGE != $geoDimensionUsage/USAGE] except $periodDimensionUsage"/> |
---|
135 | |
---|
136 | <xsl:call-template name="Interactive.mapRecordDimensionFilter"> |
---|
137 | <xsl:with-param name="recordDimensionFields" select="$recordDimensionFields"/> |
---|
138 | <xsl:with-param name="dimensionUsage" select="$geoDimensionUsage"/> |
---|
139 | <xsl:with-param name="dimension" select="$dimensions/DIMENSION[NAME=$geoDimensionUsage/NAME]"/> |
---|
140 | </xsl:call-template> |
---|
141 | <xsl:call-template name="Interactive.mapRecordDimensionFilter"> |
---|
142 | <xsl:with-param name="recordDimensionFields" select="$recordDimensionFields"/> |
---|
143 | <xsl:with-param name="dimensionUsage" select="$periodDimensionUsage"/> |
---|
144 | <xsl:with-param name="dimension" select="$dimensions/DIMENSION[NAME=$periodDimensionUsage/NAME]"/> |
---|
145 | </xsl:call-template> |
---|
146 | <xsl:call-template name="Interactive.mapRecordDimensionFilter"> |
---|
147 | <xsl:with-param name="recordDimensionFields" select="$recordDimensionFields"/> |
---|
148 | <xsl:with-param name="dimensionUsage" select="$otherDimensionUsage"/> |
---|
149 | <xsl:with-param name="dimension" select="$dimensions/DIMENSION[NAME=$otherDimensionUsage[1]/NAME]"/> |
---|
150 | </xsl:call-template> |
---|
151 | </xsl:template> |
---|
152 | |
---|
153 | <xsl:template name="Interactive.mapRecordDimensionFilter" |
---|
154 | ibis:doc="helper to locaize create actual XML map dimension inclusion struct. |
---|
155 | The fieldname is used by the script to access the data record's |
---|
156 | geo dim. Here's the struct of a JSON data record: |
---|
157 | 'rowID':'31' |
---|
158 | ,'Category':'GeoCnty.61' |
---|
159 | ,'CategoryTitle':'Valencia' |
---|
160 | ,'CategorySortOrder':33 |
---|
161 | ,'Constant':'YearGrp3Yrs.2017' |
---|
162 | ,'ConstantTitle':'2015-2017' |
---|
163 | ,'ConstantSortOrder':2015 |
---|
164 | ,'MeasureValue': 10.5 |
---|
165 | ,'MeasureValueTitle':'10.5%' |
---|
166 | " |
---|
167 | > |
---|
168 | <xsl:param name="recordDimensionFields" ibis:doc="generic, internal ser/cat/const struct."/> |
---|
169 | <xsl:param name="dimensionUsage" ibis:doc="Indicator View or QM DIMENSION_USAGE struct."/> |
---|
170 | <xsl:param name="dimension" ibis:doc="dimensions/DIMENSION[NAME=$dimensionUsage/NAME]"/> |
---|
171 | |
---|
172 | <xsl:param name="dimensionValues" select="$dimension/VALUES/VALUE[not(NOT_SELECTABLE_FLAG) and (ibis:getNormalizedText(.) = $dimensionUsage//VALUE)]"/> |
---|
173 | <xsl:param name="dimensionValue"> |
---|
174 | <xsl:choose> |
---|
175 | <!-- geo has no dim no value. Process for geo flag so no otherwise --> |
---|
176 | <xsl:when test="exists($dimension/GEOGRAPHY_FLAG)"/> |
---|
177 | <xsl:when test="exists($dimension/PERIOD_FLAG)"> |
---|
178 | <xsl:variable name="maxPeriodValue" select="max($dimensionValues/text()[1])" /> |
---|
179 | <xsl:copy-of select="$dimensionValues[number(text()[1]) = $maxPeriodValue]"/> |
---|
180 | </xsl:when> |
---|
181 | <xsl:otherwise> |
---|
182 | <xsl:copy-of select="$dimensionValues[1]"/> |
---|
183 | </xsl:otherwise> |
---|
184 | </xsl:choose> |
---|
185 | </xsl:param> |
---|
186 | |
---|
187 | <xsl:if test="$dimensionUsage/USAGE"> |
---|
188 | <RECORD_DIMENSION_FILTER> |
---|
189 | <RECORD_DIMENSION_FIELD_NAME><xsl:value-of select="$recordDimensionFields/RECORD_DIMENSION_FIELD[DIMENSION_NAMES/DIMENSION_NAME = $dimension/NAME]/NAME"/></RECORD_DIMENSION_FIELD_NAME> |
---|
190 | <DIMENSION_NAME><xsl:value-of select="$dimension/NAME"/></DIMENSION_NAME> |
---|
191 | <DIMENSION_TITLE><xsl:value-of select="ibis:getDimensionTitle($dimension)"/></DIMENSION_TITLE> |
---|
192 | <DIMENSION_VALUE><xsl:value-of select="ibis:getNormalizedText($dimensionValue/VALUE)"/></DIMENSION_VALUE> |
---|
193 | <DIMENSION_VALUE_TITLE><xsl:value-of select="ibis:getDimensionValueTitle($dimensionValue/VALUE)"/></DIMENSION_VALUE_TITLE> |
---|
194 | </RECORD_DIMENSION_FILTER> |
---|
195 | </xsl:if> |
---|
196 | </xsl:template> |
---|
197 | |
---|
198 | |
---|
199 | <xsl:template name="Interactive.indicatorViewDatasetRecords" |
---|
200 | ibis:doc="Creates a subset of the dataset records by filtering out the |
---|
201 | unused dataset records. This template loops all possible dataset |
---|
202 | records and filters out based on the supplied cat, series, const |
---|
203 | dimensions and values usages to create the data record subset. |
---|
204 | |
---|
205 | This dataset record filtering uses the dimension usages to determine |
---|
206 | if the usage and dim name/values match. |
---|
207 | |
---|
208 | This is typically only used for the IPV uses because QM datasets are |
---|
209 | very specific, alreaady filtered records. |
---|
210 | " |
---|
211 | > |
---|
212 | <xsl:param name="dimensionUsages" ibis:doc="Indicator View DIMENSION_USAGE struct that is used to filter records."/> |
---|
213 | <xsl:param name="datasetRecords" ibis:doc="typically the entire indicator's DATASET//RECORDS struct."/> |
---|
214 | <xsl:param name="recordDimensionFields" ibis:doc="generic, internal ser/cat/const struct."/> |
---|
215 | |
---|
216 | <xsl:variable name="categoryDimensionUsages" select="$dimensionUsages/DIMENSION_USAGE[USAGE='category']"/> |
---|
217 | <xsl:variable name="seriesDimensionUsages" select="$dimensionUsages/DIMENSION_USAGE[USAGE='series']"/> |
---|
218 | <xsl:variable name="constantDimensionUsages" select="$dimensionUsages/DIMENSION_USAGE[USAGE='constant']"/> |
---|
219 | |
---|
220 | <!-- no hasCatRecDimValues is not needed - required will always have --> |
---|
221 | <xsl:variable name="seriesRecordDimensionValuesCount" select="$recordDimensionFields/RECORD_DIMENSION_FIELD[DIMENSION_USAGE='series']/DIMENSION_VALUES_COUNT" as="xs:integer"/> |
---|
222 | <xsl:variable name="constantRecordDimensionValuesCount" select="$recordDimensionFields/RECORD_DIMENSION_FIELD[DIMENSION_USAGE='constant']/DIMENSION_VALUES_COUNT" as="xs:integer"/> |
---|
223 | |
---|
224 | <!-- used to filter/limit ds records that only have the same # of dims --> |
---|
225 | <xsl:variable name="dimensionUsagesCount" select="count(distinct-values($dimensionUsages/DIMENSION_USAGE/USAGE))"/> |
---|
226 | |
---|
227 | <!-- might as well filter out records that don't have the same number of dims. --> |
---|
228 | <xsl:for-each select="$datasetRecords/RECORD[count(DIMENSIONS/DIMENSION) = $dimensionUsagesCount]"> |
---|
229 | <xsl:variable name="datasetRecord" select="."/> |
---|
230 | |
---|
231 | <!-- NORMALIZE-SPACE: usage VALUE has text() and SORT_ORDER so is needed. --> |
---|
232 | <xsl:variable name="categoryDimensionUsage" select="$categoryDimensionUsages [NAME = $datasetRecord//DIMENSION/NAME]"/> |
---|
233 | <xsl:variable name="categoryRecordDimensionValueCount" select="count($datasetRecord//DIMENSION[NAME = $categoryDimensionUsage/NAME]/VALUE[text() = $categoryDimensionUsage/VALUES/VALUE/normalize-space(text()[1])])"/> |
---|
234 | |
---|
235 | <xsl:variable name="seriesDimensionUsage" select="$seriesDimensionUsages [NAME = $datasetRecord//DIMENSION/NAME]"/> |
---|
236 | <xsl:variable name="seriesRecordDimensionValueCount" select="count($datasetRecord//DIMENSION[NAME = $seriesDimensionUsage/NAME]/VALUE[text() = $seriesDimensionUsage/VALUES/VALUE/normalize-space(text()[1])])"/> |
---|
237 | |
---|
238 | <xsl:variable name="constantDimensionUsage" select="$constantDimensionUsages [NAME = $datasetRecord//DIMENSION/NAME]"/> |
---|
239 | <xsl:variable name="constantRecordDimensionValueCount" select="count($datasetRecord//DIMENSION[NAME = $constantDimensionUsage/NAME]/VALUE[text() = $constantDimensionUsage/VALUES/VALUE/normalize-space(text()[1])])"/> |
---|
240 | |
---|
241 | <!-- All records have a category but to be safe check cat exists. |
---|
242 | If constant and series defined for the view then the record |
---|
243 | MUST include them. If NO series/const defined then the |
---|
244 | record MUST NOT have any series/const dimension records. |
---|
245 | Easy way to make sure that not including records that do not |
---|
246 | have the right number of dimensions is to compare counts. |
---|
247 | NOTE: 0 = value"S"count, 0 != ValueCount. |
---|
248 | --> |
---|
249 | <xsl:if test="(0 != $categoryRecordDimensionValueCount) |
---|
250 | and ((0 = $seriesRecordDimensionValuesCount) or (0 != $seriesRecordDimensionValueCount)) |
---|
251 | and ((0 = $constantRecordDimensionValuesCount) or (0 != $constantRecordDimensionValueCount)) |
---|
252 | "> |
---|
253 | <xsl:copy-of select="$datasetRecord"/> |
---|
254 | </xsl:if> |
---|
255 | </xsl:for-each> |
---|
256 | |
---|
257 | </xsl:template> |
---|
258 | |
---|
259 | |
---|
260 | <xsl:template name="Interactive.recordAncillaryValueFields" |
---|
261 | ibis:doc="Creates the following ancillary values fields: |
---|
262 | RECORD_ANCILLARY_VALUE_FIELD |
---|
263 | NAME - ancillary value name |
---|
264 | TITLE - either label or title or name |
---|
265 | XSLT_FORMAT_PATTERN |
---|
266 | [INFO_FIELD_FLAG] - flag element for label and notes????????????? |
---|
267 | " |
---|
268 | > |
---|
269 | <xsl:param name="datasetAncillaryValues" ibis:doc="DATASET_ANCILLARY_VALUES in the QM config or IP dataset"/> |
---|
270 | <xsl:param name="ancillaryValues" ibis:doc="complete AV defs"/> |
---|
271 | <xsl:param name="valueTypes" ibis:doc="complete VT defs"/> |
---|
272 | <xsl:param name="measureFormatPattern" ibis:doc="from measure and value type."/> |
---|
273 | |
---|
274 | <xsl:for-each select="$datasetAncillaryValues/DATASET_ANCILLARY_VALUE"> |
---|
275 | <xsl:variable name="ancillaryValue" select="$ancillaryValues/ANCILLARY_VALUE[NAME = current()/ANCILLARY_VALUE_NAME]"/> |
---|
276 | <RECORD_ANCILLARY_VALUE_FIELD> |
---|
277 | <NAME><xsl:value-of select="ANCILLARY_VALUE_NAME"/></NAME> |
---|
278 | <xsl:choose> |
---|
279 | <xsl:when test="0 != string-length(ANCILLARY_VALUE_LABEL)"> |
---|
280 | <TITLE><xsl:value-of select="ANCILLARY_VALUE_LABEL"/></TITLE> |
---|
281 | </xsl:when> |
---|
282 | <xsl:when test="0 != string-length($ancillaryValue/TITLE)"> |
---|
283 | <xsl:copy-of select="$ancillaryValue/TITLE"/> |
---|
284 | </xsl:when> |
---|
285 | <xsl:otherwise> |
---|
286 | <TITLE><xsl:value-of select="ANCILLARY_VALUE_NAME"/></TITLE> |
---|
287 | </xsl:otherwise> |
---|
288 | </xsl:choose> |
---|
289 | |
---|
290 | <xsl:variable name="formatPattern" select=" |
---|
291 | if( exists( ($valueTypes//VALUE_TYPE[NAME = $ancillaryValue/VALUE_TYPE_NAME]/XSLT_FORMAT_PATTERN)[1] )) |
---|
292 | then ($valueTypes//VALUE_TYPE[NAME = $ancillaryValue/VALUE_TYPE_NAME]/XSLT_FORMAT_PATTERN)[1] |
---|
293 | else $measureFormatPattern |
---|
294 | "/> |
---|
295 | <xsl:copy-of select="$formatPattern"/> |
---|
296 | </RECORD_ANCILLARY_VALUE_FIELD> |
---|
297 | </xsl:for-each> |
---|
298 | </xsl:template> |
---|
299 | |
---|
300 | |
---|
301 | <xsl:template name="Interactive.datasetRecordTotalValues" |
---|
302 | ibis:doc="Creates the following struct for total dsr fields - used for |
---|
303 | query result total rows. |
---|
304 | |
---|
305 | DATASET_RECORD_TOTAL_VALUE |
---|
306 | NAME - 'Measure' or ANCILLARY_VALUE_NAME |
---|
307 | TITLE - formatted value. |
---|
308 | |
---|
309 | Called from DataViz.populateKendoLeafletDataVizObject if showGrid |
---|
310 | " |
---|
311 | > |
---|
312 | <xsl:param name="datasetRecords"/> |
---|
313 | <xsl:param name="recordAncillaryValueFields"/> |
---|
314 | <xsl:param name="measureFormatPattern"/> |
---|
315 | <xsl:param name="totalDimensionValue" select="'.'"/> |
---|
316 | |
---|
317 | <xsl:variable name="totalDatasetRecord" select="$datasetRecords/RECORD[not(DIMENSIONS/DIMENSION/VALUE/text() != $totalDimensionValue)]"/> |
---|
318 | <xsl:if test="(1 = count($totalDatasetRecord)) and (0 != string-length($totalDatasetRecord/MEASURE/VALUE))"> |
---|
319 | <DATASET_RECORD_TOTAL_VALUE> |
---|
320 | <NAME>Measure</NAME> |
---|
321 | <TITLE><xsl:value-of select="ibis:getFormattedNumber($totalDatasetRecord/MEASURE/VALUE, $measureFormatPattern)"/></TITLE> |
---|
322 | </DATASET_RECORD_TOTAL_VALUE> |
---|
323 | |
---|
324 | <xsl:for-each select="$recordAncillaryValueFields/RECORD_ANCILLARY_VALUE_FIELD"> |
---|
325 | <xsl:variable name="ancillaryValue" select="$totalDatasetRecord//ANCILLARY_VALUE[NAME=current()/NAME]/VALUE"/> |
---|
326 | <DATASET_RECORD_TOTAL_VALUE> |
---|
327 | <xsl:copy-of select="NAME"/> |
---|
328 | <TITLE><xsl:value-of select="ibis:getFormattedNumber($ancillaryValue, XSLT_FORMAT_PATTERN)"/></TITLE> |
---|
329 | </DATASET_RECORD_TOTAL_VALUE> |
---|
330 | </xsl:for-each> |
---|
331 | </xsl:if> |
---|
332 | </xsl:template> |
---|
333 | |
---|
334 | |
---|
335 | <xsl:template name="Interactive.csvDimensionsTitleList" |
---|
336 | ibis:doc="Internal template which builds a comma separated values |
---|
337 | (CSV) list of unique dimension label/titles. |
---|
338 | " |
---|
339 | > |
---|
340 | <xsl:param name="dimensions" ibis:doc="dimensions to look up value titles from."/> |
---|
341 | |
---|
342 | <xsl:variable name="dimensionTitles"> |
---|
343 | <xsl:for-each select="$dimensions"> |
---|
344 | <xsl:sort select="SORT_ORDER" order="ascending" data-type="number"/> |
---|
345 | <xsl:sort select="TITLE" order="ascending" data-type="text"/> |
---|
346 | <TITLE><xsl:value-of select="ibis:getDimensionTitle(.)"/></TITLE> |
---|
347 | </xsl:for-each> |
---|
348 | </xsl:variable> |
---|
349 | <xsl:for-each select="distinct-values($dimensionTitles/TITLE)"> |
---|
350 | <xsl:if test="position() != 1">, </xsl:if> |
---|
351 | <xsl:value-of select="."/> |
---|
352 | </xsl:for-each> |
---|
353 | </xsl:template> |
---|
354 | |
---|
355 | </xsl:stylesheet> |
---|
356 | <!-- ============================= End of File ============================= --> |
---|