source: shared/mod-SLOOT/trunk/functx/functx-1.0-nodoc-2007-01.xsl @ 2029

Last change on this file since 2029 was 2029, checked in by mwindhouwer, 12 years ago

Initial import of all the *cats, i.e., ISOcat, RELcat and SCHEMAcat.

File size: 59.0 KB
Line 
1
2<!--
3
4 ********************************
5 The FunctX XSLT Function Library
6 ********************************
7
8 Copyright (C) 2007 Datypic
9
10 This library is free software; you can redistribute it and/or
11 modify it under the terms of the GNU Lesser General Public
12 License as published by the Free Software Foundation; either
13 version 2.1 of the License.
14
15 This library is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 Lesser General Public License for more details.
19
20 You should have received a copy of the GNU Lesser General Public
21 License along with this library; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
23
24 For more information on the FunctX XSLT library, contact contrib@functx.com.
25
26 @version 1.0
27 @see     http://www.xsltfunctions.com
28--> 
29<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
30                xmlns:dxmlf="http://www.datypic.com/xmlf"
31                xmlns:xs="http://www.w3.org/2001/XMLSchema"
32                xmlns:fn="http://www.w3.org/2005/xpath-functions"
33                xmlns:local="http://www.datypic.com/local"
34                 xmlns:functx="http://www.functx.com" 
35                exclude-result-prefixes="dxmlf xs" version="2.0">
36 
37<xsl:function name="functx:add-attributes" as="element()?" 
38              xmlns:functx="http://www.functx.com" >
39  <xsl:param name="elements" as="element()*"/> 
40  <xsl:param name="attrNames" as="xs:QName*"/> 
41  <xsl:param name="attrValues" as="xs:anyAtomicType*"/> 
42 
43  <xsl:for-each select="$elements">
44    <xsl:variable name="element" select="."/>
45    <xsl:copy>
46      <xsl:for-each select="$attrNames">
47        <xsl:variable name="seq" select="position()"/>
48        <xsl:if test="not($element/@*[node-name(.) = current()])">
49          <xsl:attribute name="{.}"
50                         namespace="{namespace-uri-from-QName(.)}"
51                         select="$attrValues[$seq]"/>
52        </xsl:if>
53      </xsl:for-each>
54      <xsl:copy-of select="@*|node()"/>
55    </xsl:copy>
56  </xsl:for-each>
57 
58</xsl:function>
59
60
61<xsl:function name="functx:add-months" as="xs:date?" 
62              xmlns:functx="http://www.functx.com" >
63  <xsl:param name="date" as="xs:anyAtomicType?"/> 
64  <xsl:param name="months" as="xs:integer"/> 
65 
66  <xsl:sequence select="
67   xs:date($date) + functx:yearMonthDuration(0,$months)
68 "/>
69   
70</xsl:function>
71
72
73<xsl:function name="functx:add-or-update-attributes" as="element()?" 
74              xmlns:functx="http://www.functx.com" >
75  <xsl:param name="elements" as="element()*"/> 
76  <xsl:param name="attrNames" as="xs:QName*"/> 
77  <xsl:param name="attrValues" as="xs:anyAtomicType*"/> 
78 
79  <xsl:for-each select="$elements">
80    <xsl:copy>
81      <xsl:for-each select="$attrNames">
82        <xsl:variable name="seq" select="position()"/>
83        <xsl:attribute name="{.}"
84                       namespace="{namespace-uri-from-QName(.)}"
85                       select="$attrValues[$seq]"/>
86      </xsl:for-each>
87      <xsl:copy-of select="@*[not(node-name(.) = $attrNames)]|node()"/>
88    </xsl:copy>
89  </xsl:for-each>
90 
91</xsl:function>
92
93
94<xsl:function name="functx:all-whitespace" as="xs:boolean" 
95              xmlns:functx="http://www.functx.com" >
96  <xsl:param name="arg" as="xs:string?"/> 
97 
98  <xsl:sequence select="
99   normalize-space($arg) = ''
100 "/>
101   
102</xsl:function>
103
104
105<xsl:function name="functx:are-distinct-values" as="xs:boolean" 
106              xmlns:functx="http://www.functx.com" >
107  <xsl:param name="seq" as="xs:anyAtomicType*"/> 
108 
109  <xsl:sequence select="
110   count(distinct-values($seq)) = count($seq)
111 "/>
112   
113</xsl:function>
114
115
116<xsl:function name="functx:atomic-type" as="xs:string*" 
117              xmlns:functx="http://www.functx.com" >
118  <xsl:param name="values" as="xs:anyAtomicType*"/> 
119 
120  <xsl:sequence select="
121 for $val in $values
122 return
123 (if ($val instance of xs:untypedAtomic) then 'xs:untypedAtomic'
124 else if ($val instance of xs:anyURI) then 'xs:anyURI'
125 else if ($val instance of xs:string) then 'xs:string'
126 else if ($val instance of xs:QName) then 'xs:QName'
127 else if ($val instance of xs:boolean) then 'xs:boolean'
128 else if ($val instance of xs:base64Binary) then 'xs:base64Binary'
129 else if ($val instance of xs:hexBinary) then 'xs:hexBinary'
130 else if ($val instance of xs:integer) then 'xs:integer'
131 else if ($val instance of xs:decimal) then 'xs:decimal'
132 else if ($val instance of xs:float) then 'xs:float'
133 else if ($val instance of xs:double) then 'xs:double'
134 else if ($val instance of xs:date) then 'xs:date'
135 else if ($val instance of xs:time) then 'xs:time'
136 else if ($val instance of xs:dateTime) then 'xs:dateTime'
137 else if ($val instance of xs:dayTimeDuration)
138         then 'xs:dayTimeDuration'
139 else if ($val instance of xs:yearMonthDuration)
140         then 'xs:yearMonthDuration'
141 else if ($val instance of xs:duration) then 'xs:duration'
142 else if ($val instance of xs:gMonth) then 'xs:gMonth'
143 else if ($val instance of xs:gYear) then 'xs:gYear'
144 else if ($val instance of xs:gYearMonth) then 'xs:gYearMonth'
145 else if ($val instance of xs:gDay) then 'xs:gDay'
146 else if ($val instance of xs:gMonthDay) then 'xs:gMonthDay'
147 else 'unknown')
148 "/>
149   
150</xsl:function>
151
152
153<xsl:function name="functx:avg-empty-is-zero" as="xs:double" 
154              xmlns:functx="http://www.functx.com" >
155  <xsl:param name="values" as="xs:anyAtomicType*"/> 
156  <xsl:param name="allNodes" as="node()*"/> 
157 
158  <xsl:sequence select="
159   if (empty($allNodes))
160   then 0
161   else sum($values[string(.) != '']) div count($allNodes)
162 "/>
163   
164</xsl:function>
165
166
167<xsl:function name="functx:between-exclusive" as="xs:boolean" 
168              xmlns:functx="http://www.functx.com" >
169  <xsl:param name="value" as="xs:anyAtomicType?"/> 
170  <xsl:param name="minValue" as="xs:anyAtomicType"/> 
171  <xsl:param name="maxValue" as="xs:anyAtomicType"/> 
172 
173  <xsl:sequence select="
174   $value > $minValue and $value &lt; $maxValue
175 "/>
176   
177</xsl:function>
178
179
180<xsl:function name="functx:between-inclusive" as="xs:boolean" 
181              xmlns:functx="http://www.functx.com" >
182  <xsl:param name="value" as="xs:anyAtomicType?"/> 
183  <xsl:param name="minValue" as="xs:anyAtomicType"/> 
184  <xsl:param name="maxValue" as="xs:anyAtomicType"/> 
185 
186  <xsl:sequence select="
187   $value >= $minValue and $value &lt;= $maxValue
188 "/>
189   
190</xsl:function>
191
192
193<xsl:function name="functx:camel-case-to-words" as="xs:string" 
194              xmlns:functx="http://www.functx.com" >
195  <xsl:param name="arg" as="xs:string?"/> 
196  <xsl:param name="delim" as="xs:string"/> 
197 
198  <xsl:sequence select="
199   concat(substring($arg,1,1),
200             replace(substring($arg,2),'(\p{Lu})',
201                        concat($delim, '$1')))
202 "/>
203   
204</xsl:function>
205
206
207<xsl:function name="functx:capitalize-first" as="xs:string?" 
208              xmlns:functx="http://www.functx.com" >
209  <xsl:param name="arg" as="xs:string?"/> 
210 
211  <xsl:sequence select="
212   concat(upper-case(substring($arg,1,1)),
213             substring($arg,2))
214 "/>
215   
216</xsl:function>
217
218
219<xsl:function name="functx:change-element-names-deep" as="node()*" 
220              xmlns:functx="http://www.functx.com" >
221  <xsl:param name="nodes" as="node()*"/> 
222  <xsl:param name="oldNames" as="xs:QName*"/> 
223  <xsl:param name="newNames" as="xs:QName*"/> 
224 
225  <xsl:if test="count($oldNames) != count($newNames)">
226    <xsl:sequence select="error(
227         xs:QName('functx:Different_number_of_names'))"/>
228  </xsl:if>
229  <xsl:for-each select="$nodes">
230    <xsl:variable name="node" select="."/>
231    <xsl:choose>
232      <xsl:when test="$node instance of element()">
233        <xsl:variable name="theName"
234                      select="functx:if-empty
235                    ($newNames[index-of($oldNames, node-name($node))],
236                     node-name($node))"/>
237        <xsl:element name="{$theName}"
238                     namespace="{namespace-uri-from-QName($theName)}" >
239           <xsl:sequence select="($node/@*,
240                  functx:change-element-names-deep($node/node(),
241                                           $oldNames, $newNames))"/>
242        </xsl:element>
243      </xsl:when>
244      <xsl:when test="$node instance of document-node()">
245        <xsl:document>
246           <xsl:sequence select="functx:change-element-names-deep(
247                $node/node(), $oldNames, $newNames)"/>
248        </xsl:document>
249      </xsl:when>
250      <xsl:otherwise>
251        <xsl:sequence select="$node"/>
252      </xsl:otherwise>
253    </xsl:choose>
254  </xsl:for-each>
255 
256</xsl:function>
257
258
259<xsl:function name="functx:change-element-ns-deep" as="node()*" 
260              xmlns:functx="http://www.functx.com" >
261  <xsl:param name="nodes" as="node()*"/> 
262  <xsl:param name="newns" as="xs:string"/> 
263  <xsl:param name="prefix" as="xs:string"/> 
264 
265  <xsl:for-each select="$nodes">
266    <xsl:variable name="node" select="."/>
267    <xsl:choose>
268      <xsl:when test="$node instance of element()">
269        <xsl:element name="{concat($prefix,
270                                    if ($prefix = '')
271                                    then ''
272                                    else ':',
273                                    local-name($node))}"
274                     namespace="{$newns}">
275          <xsl:sequence select="($node/@*,
276                functx:change-element-ns-deep($node/node(),
277                                           $newns, $prefix))"/>
278        </xsl:element>
279      </xsl:when>
280      <xsl:when test="$node instance of document-node()">
281        <xsl:document>
282          <xsl:sequence select="functx:change-element-ns-deep(
283                $node/node(), $newns, $prefix)"/>
284        </xsl:document>
285      </xsl:when>
286      <xsl:otherwise>
287        <xsl:sequence select="$node"/>
288      </xsl:otherwise>
289   </xsl:choose>
290  </xsl:for-each>
291 
292</xsl:function>
293
294
295<xsl:function name="functx:change-element-ns" as="element()?" 
296              xmlns:functx="http://www.functx.com" >
297  <xsl:param name="elements" as="element()*"/> 
298  <xsl:param name="newns" as="xs:string"/> 
299  <xsl:param name="prefix" as="xs:string"/> 
300 
301   <xsl:for-each select="$elements">
302     <xsl:variable name="element" select="."/>
303     <xsl:element name="{concat($prefix,
304                                    if ($prefix = '')
305                                    then ''
306                                    else ':',
307                                    local-name($element))}"
308                     namespace="{$newns}">
309       <xsl:sequence select="$element/@*, $element/node()"/>
310     </xsl:element>
311   </xsl:for-each>
312 
313</xsl:function>
314
315
316<xsl:function name="functx:chars" as="xs:string*" 
317              xmlns:functx="http://www.functx.com" >
318  <xsl:param name="arg" as="xs:string?"/> 
319 
320  <xsl:sequence select="
321   for $ch in string-to-codepoints($arg)
322   return codepoints-to-string($ch)
323 "/>
324   
325</xsl:function>
326
327
328<xsl:function name="functx:contains-any-of" as="xs:boolean" 
329              xmlns:functx="http://www.functx.com" >
330  <xsl:param name="arg" as="xs:string?"/> 
331  <xsl:param name="searchStrings" as="xs:string*"/> 
332 
333  <xsl:sequence select="
334   some $searchString in $searchStrings
335   satisfies contains($arg,$searchString)
336 "/>
337   
338</xsl:function>
339
340
341<xsl:function name="functx:contains-case-insensitive" as="xs:boolean?" 
342              xmlns:functx="http://www.functx.com" >
343  <xsl:param name="arg" as="xs:string?"/> 
344  <xsl:param name="substring" as="xs:string"/> 
345 
346  <xsl:sequence select="
347   contains(upper-case($arg), upper-case($substring))
348 "/>
349   
350</xsl:function>
351
352
353<xsl:function name="functx:contains-word" as="xs:boolean" 
354              xmlns:functx="http://www.functx.com" >
355  <xsl:param name="arg" as="xs:string?"/> 
356  <xsl:param name="word" as="xs:string"/> 
357 
358  <xsl:sequence select="
359   matches(upper-case($arg),
360           concat('^(.*\W)?',
361                     upper-case(functx:escape-for-regex($word)),
362                     '(\W.*)?$'))
363 "/>
364   
365</xsl:function>
366
367
368<xsl:function name="functx:copy-attributes" as="element()" 
369              xmlns:functx="http://www.functx.com" >
370  <xsl:param name="copyTo" as="element()"/> 
371  <xsl:param name="copyFrom" as="element()"/> 
372 
373  <xsl:element name="{node-name($copyTo)}">
374    <xsl:sequence select="
375       ($copyTo/@*[not(node-name(.) = $copyFrom/@*/node-name(.))],
376        $copyFrom/@*,
377        $copyTo/node())"/>
378  </xsl:element>
379 
380</xsl:function>
381
382
383<xsl:function name="functx:date" as="xs:date" 
384              xmlns:functx="http://www.functx.com" >
385  <xsl:param name="year" as="xs:anyAtomicType"/> 
386  <xsl:param name="month" as="xs:anyAtomicType"/> 
387  <xsl:param name="day" as="xs:anyAtomicType"/> 
388 
389  <xsl:sequence select="
390   xs:date(
391     concat(
392       functx:pad-integer-to-length(xs:integer($year),4),'-',
393       functx:pad-integer-to-length(xs:integer($month),2),'-',
394       functx:pad-integer-to-length(xs:integer($day),2)))
395 "/>
396   
397</xsl:function>
398
399
400<xsl:function name="functx:dateTime" as="xs:dateTime" 
401              xmlns:functx="http://www.functx.com" >
402  <xsl:param name="year" as="xs:anyAtomicType"/> 
403  <xsl:param name="month" as="xs:anyAtomicType"/> 
404  <xsl:param name="day" as="xs:anyAtomicType"/> 
405  <xsl:param name="hour" as="xs:anyAtomicType"/> 
406  <xsl:param name="minute" as="xs:anyAtomicType"/> 
407  <xsl:param name="second" as="xs:anyAtomicType"/> 
408 
409  <xsl:sequence select="
410   xs:dateTime(
411     concat(functx:date($year,$month,$day),'T',
412             functx:time($hour,$minute,$second)))
413 "/>
414   
415</xsl:function>
416
417
418<xsl:function name="functx:day-in-year" as="xs:integer?" 
419              xmlns:functx="http://www.functx.com" >
420  <xsl:param name="date" as="xs:anyAtomicType?"/> 
421 
422  <xsl:sequence select="
423  days-from-duration(
424      xs:date($date) - functx:first-day-of-year($date)) + 1
425 "/>
426   
427</xsl:function>
428
429
430<xsl:function name="functx:day-of-week-abbrev-en" as="xs:string?" 
431              xmlns:functx="http://www.functx.com" >
432  <xsl:param name="date" as="xs:anyAtomicType?"/> 
433 
434  <xsl:sequence select="
435   ('Sun', 'Mon', 'Tues', 'Wed', 'Thurs', 'Fri', 'Sat')
436   [functx:day-of-week($date) + 1]
437 "/>
438   
439</xsl:function>
440
441
442<xsl:function name="functx:day-of-week-name-en" as="xs:string?" 
443              xmlns:functx="http://www.functx.com" >
444  <xsl:param name="date" as="xs:anyAtomicType?"/> 
445 
446  <xsl:sequence select="
447   ('Sunday', 'Monday', 'Tuesday', 'Wednesday',
448    'Thursday', 'Friday', 'Saturday')
449      [functx:day-of-week($date) + 1]
450 "/>
451   
452</xsl:function>
453
454
455<xsl:function name="functx:day-of-week" as="xs:integer?" 
456              xmlns:functx="http://www.functx.com" >
457  <xsl:param name="date" as="xs:anyAtomicType?"/> 
458 
459  <xsl:sequence select="
460  if (empty($date))
461  then ()
462  else xs:integer((xs:date($date) - xs:date('1901-01-06'))
463          div xs:dayTimeDuration('P1D')) mod 7
464 "/>
465   
466</xsl:function>
467
468
469<xsl:function name="functx:dayTimeDuration" as="xs:dayTimeDuration" 
470              xmlns:functx="http://www.functx.com" >
471  <xsl:param name="days" as="xs:decimal?"/> 
472  <xsl:param name="hours" as="xs:decimal?"/> 
473  <xsl:param name="minutes" as="xs:decimal?"/> 
474  <xsl:param name="seconds" as="xs:decimal?"/> 
475 
476  <xsl:sequence select="
477    (xs:dayTimeDuration('P1D') * functx:if-empty($days,0)) +
478    (xs:dayTimeDuration('PT1H') * functx:if-empty($hours,0)) +
479    (xs:dayTimeDuration('PT1M') * functx:if-empty($minutes,0)) +
480    (xs:dayTimeDuration('PT1S') * functx:if-empty($seconds,0))
481 "/>
482   
483</xsl:function>
484
485
486<xsl:function name="functx:days-in-month" as="xs:integer?" 
487              xmlns:functx="http://www.functx.com" >
488  <xsl:param name="date" as="xs:anyAtomicType?"/> 
489 
490  <xsl:sequence select="
491   if (month-from-date(xs:date($date)) = 2 and
492       functx:is-leap-year($date))
493   then 29
494   else
495   (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)
496    [month-from-date(xs:date($date))]
497 "/>
498   
499</xsl:function>
500
501
502<xsl:function name="functx:depth-of-node" as="xs:integer" 
503              xmlns:functx="http://www.functx.com" >
504  <xsl:param name="node" as="node()?"/> 
505 
506  <xsl:sequence select="
507   count($node/ancestor-or-self::node())
508 "/>
509   
510</xsl:function>
511
512
513<xsl:function name="functx:distinct-attribute-names" as="xs:string*" 
514              xmlns:functx="http://www.functx.com" >
515  <xsl:param name="nodes" as="node()*"/> 
516 
517  <xsl:sequence select="
518   distinct-values($nodes//@*/name(.))
519 "/>
520   
521</xsl:function>
522
523
524<xsl:function name="functx:distinct-deep" as="node()*" 
525              xmlns:functx="http://www.functx.com" >
526  <xsl:param name="nodes" as="node()*"/> 
527 
528  <xsl:sequence select="
529    for $seq in (1 to count($nodes))
530    return $nodes[$seq][not(functx:is-node-in-sequence-deep-equal(
531                          .,$nodes[position() &lt; $seq]))]
532 "/>
533   
534</xsl:function>
535
536
537<xsl:function name="functx:distinct-element-names" as="xs:string*" 
538              xmlns:functx="http://www.functx.com" >
539  <xsl:param name="nodes" as="node()*"/> 
540 
541  <xsl:sequence select="
542   distinct-values($nodes/descendant-or-self::*/name(.))
543 "/>
544   
545</xsl:function>
546
547
548<xsl:function name="functx:distinct-element-paths" as="xs:string*" 
549              xmlns:functx="http://www.functx.com" >
550  <xsl:param name="nodes" as="node()*"/> 
551 
552  <xsl:sequence select="
553   distinct-values(functx:path-to-node($nodes/descendant-or-self::*))
554 "/>
555   
556</xsl:function>
557
558
559<xsl:function name="functx:distinct-nodes" as="node()*" 
560              xmlns:functx="http://www.functx.com" >
561  <xsl:param name="nodes" as="node()*"/> 
562 
563  <xsl:sequence select="
564    for $seq in (1 to count($nodes))
565    return $nodes[$seq][not(functx:is-node-in-sequence(
566                                .,$nodes[position() &lt; $seq]))]
567 "/>
568   
569</xsl:function>
570
571
572<xsl:function name="functx:duration-from-timezone" as="xs:dayTimeDuration" 
573              xmlns:functx="http://www.functx.com" >
574  <xsl:param name="timezone" as="xs:string"/> 
575 
576  <xsl:sequence select="
577   xs:dayTimeDuration(
578     if (not(matches($timezone,'Z|[\+\-]\d{2}:\d{2}')))
579     then error(xs:QName('functx:Invalid_Timezone_Value'))
580     else if ($timezone = 'Z')
581     then 'PT0S'
582     else replace($timezone,'\+?(\d{2}):\d{2}','PT$1H')
583        )
584 "/>
585   
586</xsl:function>
587
588
589<xsl:function name="functx:dynamic-path" as="item()*" 
590              xmlns:functx="http://www.functx.com" >
591  <xsl:param name="parent" as="node()"/> 
592  <xsl:param name="path" as="xs:string"/> 
593 
594  <xsl:variable name="nextStep"
595        select="functx:substring-before-if-contains($path,'/')"/>
596  <xsl:variable name="restOfSteps"
597        select="substring-after($path,'/')"/>
598  <xsl:for-each select="
599    ($parent/*[functx:name-test(name(),$nextStep)],
600     $parent/@*[functx:name-test(name(),
601                              substring-after($nextStep,'@'))])">
602    <xsl:variable name="child" select="."/>
603    <xsl:sequence select="if ($restOfSteps)
604         then functx:dynamic-path($child, $restOfSteps)
605         else $child"/>
606  </xsl:for-each>
607 
608</xsl:function>
609
610
611<xsl:function name="functx:escape-for-regex" as="xs:string" 
612              xmlns:functx="http://www.functx.com" >
613  <xsl:param name="arg" as="xs:string?"/> 
614 
615  <xsl:sequence select="
616   replace($arg,
617           '(\.|\[|\]|\\|\||\-|\^|\$|\?|\*|\+|\{|\}|\(|\))','\\$1')
618 "/>
619   
620</xsl:function>
621
622
623<xsl:function name="functx:exclusive-or" as="xs:boolean?" 
624              xmlns:functx="http://www.functx.com" >
625  <xsl:param name="arg1" as="xs:boolean?"/> 
626  <xsl:param name="arg2" as="xs:boolean?"/> 
627 
628  <xsl:sequence select="
629   $arg1 != $arg2
630 "/>
631   
632</xsl:function>
633
634
635<xsl:function name="functx:first-day-of-month" as="xs:date?" 
636              xmlns:functx="http://www.functx.com" >
637  <xsl:param name="date" as="xs:anyAtomicType?"/> 
638 
639  <xsl:sequence select="
640   functx:date(year-from-date(xs:date($date)),
641            month-from-date(xs:date($date)),
642            1)
643 "/>
644   
645</xsl:function>
646
647
648<xsl:function name="functx:first-day-of-year" as="xs:date?" 
649              xmlns:functx="http://www.functx.com" >
650  <xsl:param name="date" as="xs:anyAtomicType?"/> 
651 
652  <xsl:sequence select="
653   functx:date(year-from-date(xs:date($date)), 1, 1)
654 "/>
655   
656</xsl:function>
657
658
659<xsl:function name="functx:first-node" as="node()?" 
660              xmlns:functx="http://www.functx.com" >
661  <xsl:param name="nodes" as="node()*"/> 
662 
663  <xsl:sequence select="
664   ($nodes/.)[1]
665 "/>
666   
667</xsl:function>
668
669
670<xsl:function name="functx:follows-not-descendant" as="xs:boolean" 
671              xmlns:functx="http://www.functx.com" >
672  <xsl:param name="a" as="node()?"/> 
673  <xsl:param name="b" as="node()?"/> 
674 
675  <xsl:sequence select="
676   $a >> $b and empty($b intersect $a/ancestor::node())
677 "/>
678   
679</xsl:function>
680
681
682<xsl:function name="functx:format-as-title-en" as="xs:string*" 
683              xmlns:functx="http://www.functx.com" >
684  <xsl:param name="titles" as="xs:string*"/> 
685 
686   <xsl:variable name="wordsToMoveToEnd"
687                 select="('A', 'An', 'The')"/>
688   <xsl:for-each select="$titles">
689     <xsl:variable name="title" select="."/>
690     <xsl:variable name="firstWord"
691          select="functx:substring-before-match($title,'\W')"/>
692     <xsl:sequence select="if ($firstWord = $wordsToMoveToEnd)
693          then replace($title,'(.*?)\W(.*)', '$2, $1')
694          else $title"/>
695   </xsl:for-each>
696 
697</xsl:function>
698
699
700<xsl:function name="functx:fragment-from-uri" as="xs:string?" 
701              xmlns:functx="http://www.functx.com" >
702  <xsl:param name="uri" as="xs:string?"/> 
703 
704  <xsl:sequence select="
705   substring-after($uri,'#')
706 "/>
707   
708</xsl:function>
709
710
711<xsl:function name="functx:has-element-only-content" as="xs:boolean" 
712              xmlns:functx="http://www.functx.com" >
713  <xsl:param name="element" as="element()"/> 
714 
715  <xsl:sequence select="
716   not($element/text()[normalize-space(.) != '']) and $element/*
717 "/>
718   
719</xsl:function>
720
721
722<xsl:function name="functx:has-empty-content" as="xs:boolean" 
723              xmlns:functx="http://www.functx.com" >
724  <xsl:param name="element" as="element()"/> 
725 
726  <xsl:sequence select="
727   not($element/node())
728 "/>
729   
730</xsl:function>
731
732
733<xsl:function name="functx:has-mixed-content" as="xs:boolean" 
734              xmlns:functx="http://www.functx.com" >
735  <xsl:param name="element" as="element()"/> 
736 
737  <xsl:sequence select="
738   $element/text()[normalize-space(.) != ''] and $element/*
739 "/>
740   
741</xsl:function>
742
743
744<xsl:function name="functx:has-simple-content" as="xs:boolean" 
745              xmlns:functx="http://www.functx.com" >
746  <xsl:param name="element" as="element()"/> 
747 
748  <xsl:sequence select="
749   $element/text() and not($element/*)
750 "/>
751   
752</xsl:function>
753
754
755<xsl:function name="functx:id-from-element" as="xs:string?" 
756              xmlns:functx="http://www.functx.com" >
757  <xsl:param name="element" as="element()?"/> 
758 
759  <xsl:sequence select="
760  data(($element/@*[id(.) is ..])[1])
761 "/>
762   
763</xsl:function>
764
765
766<xsl:function name="functx:id-untyped" as="element()*" 
767              xmlns:functx="http://www.functx.com" >
768  <xsl:param name="node" as="node()*"/> 
769  <xsl:param name="id" as="xs:anyAtomicType"/> 
770 
771  <xsl:sequence select="
772  $node//*[@* = $id]
773 "/>
774   
775</xsl:function>
776
777
778<xsl:function name="functx:if-absent" as="item()*" 
779              xmlns:functx="http://www.functx.com" >
780  <xsl:param name="arg" as="item()*"/> 
781  <xsl:param name="value" as="item()*"/> 
782 
783  <xsl:sequence select="
784    if (exists($arg))
785    then $arg
786    else $value
787 "/>
788   
789</xsl:function>
790
791
792<xsl:function name="functx:if-empty" as="item()*" 
793              xmlns:functx="http://www.functx.com" >
794  <xsl:param name="arg" as="item()?"/> 
795  <xsl:param name="value" as="item()*"/> 
796 
797  <xsl:sequence select="
798  if (string($arg) != '')
799  then data($arg)
800  else $value
801 "/>
802   
803</xsl:function>
804
805
806<xsl:function name="functx:index-of-deep-equal-node" as="xs:integer*" 
807              xmlns:functx="http://www.functx.com" >
808  <xsl:param name="nodes" as="node()*"/> 
809  <xsl:param name="nodeToFind" as="node()"/> 
810 
811  <xsl:sequence select="
812  for $seq in (1 to count($nodes))
813  return $seq[deep-equal($nodes[$seq],$nodeToFind)]
814 "/>
815   
816</xsl:function>
817
818
819<xsl:function name="functx:index-of-match-first" as="xs:integer?" 
820              xmlns:functx="http://www.functx.com" >
821  <xsl:param name="arg" as="xs:string?"/> 
822  <xsl:param name="pattern" as="xs:string"/> 
823 
824  <xsl:sequence select="
825  if (matches($arg,$pattern))
826  then string-length(tokenize($arg, $pattern)[1]) + 1
827  else ()
828 "/>
829   
830</xsl:function>
831
832
833<xsl:function name="functx:index-of-node" as="xs:integer*" 
834              xmlns:functx="http://www.functx.com" >
835  <xsl:param name="nodes" as="node()*"/> 
836  <xsl:param name="nodeToFind" as="node()"/> 
837 
838  <xsl:sequence select="
839  for $seq in (1 to count($nodes))
840  return $seq[$nodes[$seq] is $nodeToFind]
841 "/>
842   
843</xsl:function>
844
845
846<xsl:function name="functx:index-of-string-first" as="xs:integer?" 
847              xmlns:functx="http://www.functx.com" >
848  <xsl:param name="arg" as="xs:string?"/> 
849  <xsl:param name="substring" as="xs:string"/> 
850 
851  <xsl:sequence select="
852  if (contains($arg, $substring))
853  then string-length(substring-before($arg, $substring))+1
854  else ()
855 "/>
856   
857</xsl:function>
858
859
860<xsl:function name="functx:index-of-string-last" as="xs:integer?" 
861              xmlns:functx="http://www.functx.com" >
862  <xsl:param name="arg" as="xs:string?"/> 
863  <xsl:param name="substring" as="xs:string"/> 
864 
865  <xsl:sequence select="
866  functx:index-of-string($arg, $substring)[last()]
867 "/>
868   
869</xsl:function>
870
871
872<xsl:function name="functx:index-of-string" as="xs:integer*" 
873              xmlns:functx="http://www.functx.com" >
874  <xsl:param name="arg" as="xs:string?"/> 
875  <xsl:param name="substring" as="xs:string"/> 
876 
877  <xsl:sequence select="
878  if (contains($arg, $substring))
879  then (string-length(substring-before($arg, $substring))+1,
880        for $other in
881           functx:index-of-string(substring-after($arg, $substring),
882                               $substring)
883        return
884          $other +
885          string-length(substring-before($arg, $substring)) +
886          string-length($substring))
887  else ()
888 "/>
889   
890</xsl:function>
891
892
893<xsl:function name="functx:insert-string" as="xs:string" 
894              xmlns:functx="http://www.functx.com" >
895  <xsl:param name="originalString" as="xs:string?"/> 
896  <xsl:param name="stringToInsert" as="xs:string?"/> 
897  <xsl:param name="pos" as="xs:integer"/> 
898 
899  <xsl:sequence select="
900   concat(substring($originalString,1,$pos - 1),
901             $stringToInsert,
902             substring($originalString,$pos))
903 "/>
904   
905</xsl:function>
906
907
908<xsl:function name="functx:is-a-number" as="xs:boolean" 
909              xmlns:functx="http://www.functx.com" >
910  <xsl:param name="value" as="xs:anyAtomicType?"/> 
911 
912  <xsl:sequence select="
913   string(number($value)) != 'NaN'
914 "/>
915   
916</xsl:function>
917
918
919<xsl:function name="functx:is-absolute-uri" as="xs:boolean" 
920              xmlns:functx="http://www.functx.com" >
921  <xsl:param name="uri" as="xs:string?"/> 
922 
923  <xsl:sequence select="
924   matches($uri,'^[a-z]+:')
925 "/>
926   
927</xsl:function>
928
929
930<xsl:function name="functx:is-ancestor" as="xs:boolean" 
931              xmlns:functx="http://www.functx.com" >
932  <xsl:param name="node1" as="node()"/> 
933  <xsl:param name="node2" as="node()"/> 
934 
935  <xsl:sequence select="
936   exists($node1 intersect $node2/ancestor::node())
937 "/>
938   
939</xsl:function>
940
941
942<xsl:function name="functx:is-descendant" as="xs:boolean" 
943              xmlns:functx="http://www.functx.com" >
944  <xsl:param name="node1" as="node()"/> 
945  <xsl:param name="node2" as="node()"/> 
946 
947  <xsl:sequence select="
948   boolean($node2 intersect $node1/ancestor::node())
949 "/>
950   
951</xsl:function>
952
953
954<xsl:function name="functx:is-leap-year" as="xs:boolean" 
955              xmlns:functx="http://www.functx.com" >
956  <xsl:param name="date" as="xs:anyAtomicType?"/> 
957 
958  <xsl:sequence select="
959    for $year in xs:integer(substring(string($date),1,4))
960    return ($year mod 4 = 0 and
961            $year mod 100 != 0) or
962            $year mod 400 = 0
963 "/>
964   
965</xsl:function>
966
967
968<xsl:function name="functx:is-node-among-descendants-deep-equal" as="xs:boolean" 
969              xmlns:functx="http://www.functx.com" >
970  <xsl:param name="node" as="node()?"/> 
971  <xsl:param name="seq" as="node()*"/> 
972 
973  <xsl:sequence select="
974   some $nodeInSeq in $seq/descendant-or-self::*/(.|@*)
975   satisfies deep-equal($nodeInSeq,$node)
976 "/>
977   
978</xsl:function>
979
980
981<xsl:function name="functx:is-node-among-descendants" as="xs:boolean" 
982              xmlns:functx="http://www.functx.com" >
983  <xsl:param name="node" as="node()?"/> 
984  <xsl:param name="seq" as="node()*"/> 
985 
986  <xsl:sequence select="
987   some $nodeInSeq in $seq/descendant-or-self::*/(.|@*)
988   satisfies $nodeInSeq is $node
989 "/>
990   
991</xsl:function>
992
993
994<xsl:function name="functx:is-node-in-sequence-deep-equal" as="xs:boolean" 
995              xmlns:functx="http://www.functx.com" >
996  <xsl:param name="node" as="node()?"/> 
997  <xsl:param name="seq" as="node()*"/> 
998 
999  <xsl:sequence select="
1000   some $nodeInSeq in $seq satisfies deep-equal($nodeInSeq,$node)
1001 "/>
1002   
1003</xsl:function>
1004
1005
1006<xsl:function name="functx:is-node-in-sequence" as="xs:boolean" 
1007              xmlns:functx="http://www.functx.com" >
1008  <xsl:param name="node" as="node()?"/> 
1009  <xsl:param name="seq" as="node()*"/> 
1010 
1011  <xsl:sequence select="
1012   some $nodeInSeq in $seq satisfies $nodeInSeq is $node
1013 "/>
1014   
1015</xsl:function>
1016
1017
1018<xsl:function name="functx:is-value-in-sequence" as="xs:boolean" 
1019              xmlns:functx="http://www.functx.com" >
1020  <xsl:param name="value" as="xs:anyAtomicType?"/> 
1021  <xsl:param name="seq" as="xs:anyAtomicType*"/> 
1022 
1023  <xsl:sequence select="
1024   $value = $seq
1025 "/>
1026   
1027</xsl:function>
1028
1029
1030<xsl:function name="functx:last-day-of-month" as="xs:date?" 
1031              xmlns:functx="http://www.functx.com" >
1032  <xsl:param name="date" as="xs:anyAtomicType?"/> 
1033 
1034  <xsl:sequence select="
1035   functx:date(year-from-date(xs:date($date)),
1036            month-from-date(xs:date($date)),
1037            functx:days-in-month($date))
1038 "/>
1039   
1040</xsl:function>
1041
1042
1043<xsl:function name="functx:last-day-of-year" as="xs:date?" 
1044              xmlns:functx="http://www.functx.com" >
1045  <xsl:param name="date" as="xs:anyAtomicType?"/> 
1046 
1047  <xsl:sequence select="
1048   functx:date(year-from-date(xs:date($date)), 12, 31)
1049 "/>
1050   
1051</xsl:function>
1052
1053
1054<xsl:function name="functx:last-node" as="node()?" 
1055              xmlns:functx="http://www.functx.com" >
1056  <xsl:param name="nodes" as="node()*"/> 
1057 
1058  <xsl:sequence select="
1059   ($nodes/.)[last()]
1060 "/>
1061   
1062</xsl:function>
1063
1064
1065<xsl:function name="functx:leaf-elements" as="element()*" 
1066              xmlns:functx="http://www.functx.com" >
1067  <xsl:param name="root" as="node()?"/> 
1068 
1069  <xsl:sequence select="
1070   $root/descendant-or-self::*[not(*)]
1071 "/>
1072   
1073</xsl:function>
1074
1075
1076<xsl:function name="functx:left-trim" as="xs:string" 
1077              xmlns:functx="http://www.functx.com" >
1078  <xsl:param name="arg" as="xs:string?"/> 
1079 
1080  <xsl:sequence select="
1081   replace($arg,'^\s+','')
1082 "/>
1083   
1084</xsl:function>
1085
1086
1087<xsl:function name="functx:line-count" as="xs:integer" 
1088              xmlns:functx="http://www.functx.com" >
1089  <xsl:param name="arg" as="xs:string?"/> 
1090 
1091  <xsl:sequence select="
1092   count(functx:lines($arg))
1093 "/>
1094   
1095</xsl:function>
1096
1097
1098<xsl:function name="functx:lines" as="xs:string*" 
1099              xmlns:functx="http://www.functx.com" >
1100  <xsl:param name="arg" as="xs:string?"/> 
1101 
1102  <xsl:sequence select="
1103   tokenize($arg, '(\r\n?|\n\r?)')
1104 "/>
1105   
1106</xsl:function>
1107
1108
1109<xsl:function name="functx:max-depth" as="xs:integer?" 
1110              xmlns:functx="http://www.functx.com" >
1111  <xsl:param name="root" as="node()?"/> 
1112 
1113  <xsl:sequence select="
1114   if ($root/*)
1115   then max($root/*/functx:max-depth(.)) + 1
1116   else 1
1117 "/>
1118   
1119</xsl:function>
1120
1121
1122<xsl:function name="functx:max-determine-type" as="xs:anyAtomicType?" 
1123              xmlns:functx="http://www.functx.com" >
1124  <xsl:param name="seq" as="xs:anyAtomicType*"/> 
1125 
1126  <xsl:sequence select="
1127   if (every $value in $seq satisfies ($value castable as xs:double))
1128   then max(for $value in $seq return xs:double($value))
1129   else max(for $value in $seq return xs:string($value))
1130 "/>
1131   
1132</xsl:function>
1133
1134
1135<xsl:function name="functx:max-line-length" as="xs:integer" 
1136              xmlns:functx="http://www.functx.com" >
1137  <xsl:param name="arg" as="xs:string?"/> 
1138 
1139  <xsl:sequence select="
1140   max(
1141     for $line in functx:lines($arg)
1142     return string-length($line))
1143 "/>
1144   
1145</xsl:function>
1146
1147
1148<xsl:function name="functx:max-node" as="node()*" 
1149              xmlns:functx="http://www.functx.com" >
1150  <xsl:param name="nodes" as="node()*"/> 
1151 
1152  <xsl:sequence select="
1153   $nodes[. = max($nodes)]
1154 "/>
1155   
1156</xsl:function>
1157
1158
1159<xsl:function name="functx:max-string" as="xs:string?" 
1160              xmlns:functx="http://www.functx.com" >
1161  <xsl:param name="strings" as="xs:anyAtomicType*"/> 
1162 
1163  <xsl:sequence select="
1164   max(for $string in $strings return string($string))
1165 "/>
1166   
1167</xsl:function>
1168
1169
1170<xsl:function name="functx:min-determine-type" as="xs:anyAtomicType?" 
1171              xmlns:functx="http://www.functx.com" >
1172  <xsl:param name="seq" as="xs:anyAtomicType*"/> 
1173 
1174  <xsl:sequence select="
1175   if (every $value in $seq satisfies ($value castable as xs:double))
1176   then min(for $value in $seq return xs:double($value))
1177   else min(for $value in $seq return xs:string($value))
1178 "/>
1179   
1180</xsl:function>
1181
1182
1183<xsl:function name="functx:min-node" as="node()*" 
1184              xmlns:functx="http://www.functx.com" >
1185  <xsl:param name="nodes" as="node()*"/> 
1186 
1187  <xsl:sequence select="
1188   $nodes[. = min($nodes)]
1189 "/>
1190   
1191</xsl:function>
1192
1193
1194<xsl:function name="functx:min-non-empty-string" as="xs:string?" 
1195              xmlns:functx="http://www.functx.com" >
1196  <xsl:param name="strings" as="xs:string*"/> 
1197 
1198  <xsl:sequence select="
1199   min($strings[. != ''])
1200 "/>
1201   
1202</xsl:function>
1203
1204
1205<xsl:function name="functx:min-string" as="xs:string?" 
1206              xmlns:functx="http://www.functx.com" >
1207  <xsl:param name="strings" as="xs:anyAtomicType*"/> 
1208 
1209  <xsl:sequence select="
1210   min(for $string in $strings return string($string))
1211 "/>
1212   
1213</xsl:function>
1214
1215
1216<xsl:function name="functx:mmddyyyy-to-date" as="xs:date?" 
1217              xmlns:functx="http://www.functx.com" >
1218  <xsl:param name="dateString" as="xs:string?"/> 
1219 
1220  <xsl:sequence select="
1221   if (empty($dateString))
1222   then ()
1223   else if (not(matches($dateString,
1224                        '^\D*(\d{2})\D*(\d{2})\D*(\d{4})\D*$')))
1225   then error(xs:QName('functx:Invalid_Date_Format'))
1226   else xs:date(replace($dateString,
1227                        '^\D*(\d{2})\D*(\d{2})\D*(\d{4})\D*$',
1228                        '$3-$1-$2'))
1229 "/>
1230   
1231</xsl:function>
1232
1233
1234<xsl:function name="functx:month-abbrev-en" as="xs:string?" 
1235              xmlns:functx="http://www.functx.com" >
1236  <xsl:param name="date" as="xs:anyAtomicType?"/> 
1237 
1238  <xsl:sequence select="
1239   ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
1240    'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec')
1241    [month-from-date(xs:date($date))]
1242 "/>
1243   
1244</xsl:function>
1245
1246
1247<xsl:function name="functx:month-name-en" as="xs:string?" 
1248              xmlns:functx="http://www.functx.com" >
1249  <xsl:param name="date" as="xs:anyAtomicType?"/> 
1250 
1251  <xsl:sequence select="
1252   ('January', 'February', 'March', 'April', 'May', 'June',
1253    'July', 'August', 'September', 'October', 'November', 'December')
1254   [month-from-date(xs:date($date))]
1255 "/>
1256   
1257</xsl:function>
1258
1259
1260<xsl:function name="functx:name-test" as="xs:boolean" 
1261              xmlns:functx="http://www.functx.com" >
1262  <xsl:param name="testname" as="xs:string?"/> 
1263  <xsl:param name="names" as="xs:string*"/> 
1264 
1265  <xsl:sequence select="
1266$testname = $names
1267or
1268$names = '*'
1269or
1270functx:substring-after-if-contains($testname,':') =
1271   (for $name in $names
1272   return substring-after($name,'*:'))
1273or
1274substring-before($testname,':') =
1275   (for $name in $names[contains(.,':*')]
1276   return substring-before($name,':*'))
1277 "/>
1278   
1279</xsl:function>
1280
1281
1282<xsl:function name="functx:namespaces-in-use" as="xs:anyURI*" 
1283              xmlns:functx="http://www.functx.com" >
1284  <xsl:param name="root" as="node()?"/> 
1285 
1286  <xsl:sequence select="
1287   distinct-values(
1288      $root/descendant-or-self::*/(.|@*)/namespace-uri(.))
1289 "/>
1290   
1291</xsl:function>
1292
1293
1294<xsl:function name="functx:next-day" as="xs:date?" 
1295              xmlns:functx="http://www.functx.com" >
1296  <xsl:param name="date" as="xs:anyAtomicType?"/> 
1297 
1298  <xsl:sequence select="
1299   xs:date($date) + xs:dayTimeDuration('P1D')
1300 "/>
1301   
1302</xsl:function>
1303
1304
1305<xsl:function name="functx:node-kind" as="xs:string*" 
1306              xmlns:functx="http://www.functx.com" >
1307  <xsl:param name="nodes" as="node()*"/> 
1308 
1309  <xsl:sequence select="
1310 for $node in $nodes
1311 return
1312 if ($node instance of element()) then 'element'
1313 else if ($node instance of attribute()) then 'attribute'
1314 else if ($node instance of text()) then 'text'
1315 else if ($node instance of document-node()) then 'document-node'
1316 else if ($node instance of comment()) then 'comment'
1317 else if ($node instance of processing-instruction())
1318         then 'processing-instruction'
1319 else 'unknown'
1320 "/>
1321   
1322</xsl:function>
1323
1324
1325<xsl:function name="functx:non-distinct-values" as="xs:anyAtomicType*" 
1326              xmlns:functx="http://www.functx.com" >
1327  <xsl:param name="seq" as="xs:anyAtomicType*"/> 
1328 
1329  <xsl:sequence select="
1330   for $val in distinct-values($seq)
1331   return $val[count($seq[. = $val]) > 1]
1332 "/>
1333   
1334</xsl:function>
1335
1336
1337<xsl:function name="functx:number-of-matches" as="xs:integer" 
1338              xmlns:functx="http://www.functx.com" >
1339  <xsl:param name="arg" as="xs:string?"/> 
1340  <xsl:param name="pattern" as="xs:string"/> 
1341 
1342  <xsl:sequence select="
1343   count(tokenize($arg,$pattern)) - 1
1344 "/>
1345   
1346</xsl:function>
1347
1348
1349<xsl:function name="functx:open-ref-document" as="document-node()" 
1350              xmlns:functx="http://www.functx.com" >
1351  <xsl:param name="refNode" as="node()"/> 
1352 
1353  <xsl:sequence select="
1354   if (base-uri($refNode))
1355   then doc(resolve-uri($refNode, base-uri($refNode)))
1356   else doc(resolve-uri($refNode))
1357 "/>
1358   
1359</xsl:function>
1360
1361
1362<xsl:function name="functx:ordinal-number-en" as="xs:string" 
1363              xmlns:functx="http://www.functx.com" >
1364  <xsl:param name="num" as="xs:integer?"/> 
1365 
1366  <xsl:sequence select="
1367   concat(xs:string($num),
1368         if (matches(xs:string($num),'[04-9]$|1[1-3]$')) then 'th'
1369         else if (ends-with(xs:string($num),'1')) then 'st'
1370         else if (ends-with(xs:string($num),'2')) then 'nd'
1371         else if (ends-with(xs:string($num),'3')) then 'rd'
1372         else '')
1373 "/>
1374   
1375</xsl:function>
1376
1377
1378<xsl:function name="functx:pad-integer-to-length" as="xs:string" 
1379              xmlns:functx="http://www.functx.com" >
1380  <xsl:param name="integerToPad" as="xs:anyAtomicType?"/> 
1381  <xsl:param name="length" as="xs:integer"/> 
1382 
1383  <xsl:sequence select="
1384   if ($length &lt; string-length(string($integerToPad)))
1385   then error(xs:QName('functx:Integer_Longer_Than_Length'))
1386   else concat
1387         (functx:repeat-string(
1388            '0',$length - string-length(string($integerToPad))),
1389          string($integerToPad))
1390 "/>
1391   
1392</xsl:function>
1393
1394
1395<xsl:function name="functx:pad-string-to-length" as="xs:string" 
1396              xmlns:functx="http://www.functx.com" >
1397  <xsl:param name="stringToPad" as="xs:string?"/> 
1398  <xsl:param name="padChar" as="xs:string"/> 
1399  <xsl:param name="length" as="xs:integer"/> 
1400 
1401  <xsl:sequence select="
1402   substring(
1403     string-join (
1404       ($stringToPad, for $i in (1 to $length) return $padChar)
1405       ,'')
1406    ,1,$length)
1407 "/>
1408   
1409</xsl:function>
1410
1411
1412<xsl:function name="functx:path-to-node-with-pos" as="xs:string" 
1413              xmlns:functx="http://www.functx.com" >
1414  <xsl:param name="node" as="node()?"/> 
1415 
1416 <xsl:variable name="names" as="xs:string*">
1417   <xsl:for-each select="$node/ancestor-or-self::*">
1418     <xsl:variable name="ancestor" select="."/>
1419     <xsl:variable name="sibsOfSameName"
1420           select="$ancestor/../*[name() = name($ancestor)]"/>
1421     <xsl:sequence select="concat(name($ancestor),
1422         if (count($sibsOfSameName) &lt;= 1)
1423         then ''
1424         else concat(
1425        '[',functx:index-of-node($sibsOfSameName,$ancestor),']'))"/>
1426   </xsl:for-each>
1427 </xsl:variable>
1428 <xsl:sequence select="string-join($names,'/')"/>
1429 
1430</xsl:function>
1431
1432
1433<xsl:function name="functx:path-to-node" as="xs:string*" 
1434              xmlns:functx="http://www.functx.com" >
1435  <xsl:param name="nodes" as="node()*"/> 
1436 
1437  <xsl:sequence select="
1438$nodes/string-join(ancestor-or-self::*/name(.), '/')
1439 "/>
1440   
1441</xsl:function>
1442
1443
1444<xsl:function name="functx:precedes-not-ancestor" as="xs:boolean" 
1445              xmlns:functx="http://www.functx.com" >
1446  <xsl:param name="a" as="node()?"/> 
1447  <xsl:param name="b" as="node()?"/> 
1448 
1449  <xsl:sequence select="
1450   $a &lt;&lt; $b and empty($a intersect $b/ancestor::node())
1451 "/>
1452   
1453</xsl:function>
1454
1455
1456<xsl:function name="functx:previous-day" as="xs:date?" 
1457              xmlns:functx="http://www.functx.com" >
1458  <xsl:param name="date" as="xs:anyAtomicType?"/> 
1459 
1460  <xsl:sequence select="
1461   xs:date($date) - xs:dayTimeDuration('P1D')
1462 "/>
1463   
1464</xsl:function>
1465
1466
1467<xsl:function name="functx:remove-attributes-deep" as="node()*" 
1468              xmlns:functx="http://www.functx.com" >
1469  <xsl:param name="nodes" as="node()*"/> 
1470  <xsl:param name="names" as="xs:string*"/> 
1471 
1472   <xsl:for-each select="$nodes">
1473     <xsl:choose>
1474       <xsl:when test=". instance of element()">
1475         <xsl:element name="{node-name(.)}">
1476           <xsl:sequence select="
1477              (@*[not(functx:name-test(name(),$names))],
1478               functx:remove-attributes-deep(node(), $names))"/>
1479         </xsl:element>
1480       </xsl:when>
1481       <xsl:when test=". instance of document-node()">
1482         <xsl:document>
1483           <xsl:sequence select="
1484                functx:remove-attributes-deep(node(), $names)"/>
1485         </xsl:document>
1486       </xsl:when>
1487       <xsl:otherwise>
1488         <xsl:sequence select="."/>
1489       </xsl:otherwise>
1490     </xsl:choose>
1491   </xsl:for-each>
1492 
1493</xsl:function>
1494
1495
1496<xsl:function name="functx:remove-attributes" as="element()" 
1497              xmlns:functx="http://www.functx.com" >
1498  <xsl:param name="elements" as="element()*"/> 
1499  <xsl:param name="names" as="xs:string*"/> 
1500 
1501   <xsl:for-each select="$elements">
1502     <xsl:element name="{node-name(.)}">
1503       <xsl:sequence
1504         select="(@*[not(functx:name-test(name(),$names))],
1505                 node())"/>
1506     </xsl:element>
1507   </xsl:for-each>
1508 
1509</xsl:function>
1510
1511
1512<xsl:function name="functx:remove-elements-deep" as="node()*" 
1513              xmlns:functx="http://www.functx.com" >
1514  <xsl:param name="nodes" as="node()*"/> 
1515  <xsl:param name="names" as="xs:string*"/> 
1516 
1517   <xsl:for-each select="$nodes">
1518     <xsl:choose>
1519       <xsl:when test=". instance of element()">
1520         <xsl:if test="not(functx:name-test(name(),$names))">
1521           <xsl:element name="{node-name(.)}">
1522             <xsl:sequence select="@*,
1523                  functx:remove-elements-deep(node(), $names)"/>
1524           </xsl:element>
1525         </xsl:if>
1526       </xsl:when>
1527       <xsl:when test=". instance of document-node()">
1528         <xsl:document>
1529             <xsl:sequence select="
1530                  functx:remove-elements-deep(node(), $names)"/>
1531         </xsl:document>
1532       </xsl:when>
1533       <xsl:otherwise>
1534         <xsl:sequence select="."/>
1535       </xsl:otherwise>
1536     </xsl:choose>
1537   </xsl:for-each>
1538 
1539</xsl:function>
1540
1541
1542<xsl:function name="functx:remove-elements-not-contents" as="node()*" 
1543              xmlns:functx="http://www.functx.com" >
1544  <xsl:param name="nodes" as="node()*"/> 
1545  <xsl:param name="names" as="xs:string*"/> 
1546 
1547   <xsl:for-each select="$nodes">
1548     <xsl:choose>
1549       <xsl:when test=". instance of element()">
1550         <xsl:choose>
1551           <xsl:when test="functx:name-test(name(),$names)">
1552             <xsl:sequence select="
1553                 functx:remove-elements-not-contents(node(), $names)"/>
1554           </xsl:when>
1555           <xsl:otherwise>
1556             <xsl:element name="{node-name(.)}">
1557               <xsl:sequence select="@*,
1558                 functx:remove-elements-not-contents(node(),$names)"/>
1559             </xsl:element>
1560           </xsl:otherwise>
1561         </xsl:choose>
1562       </xsl:when>
1563       <xsl:when test=". instance of document-node()">
1564         <xsl:document>
1565             <xsl:sequence select="
1566                 functx:remove-elements-not-contents(node(), $names)"/>
1567         </xsl:document>
1568       </xsl:when>
1569       <xsl:otherwise>
1570         <xsl:sequence select="."/>
1571       </xsl:otherwise>
1572     </xsl:choose>
1573   </xsl:for-each>
1574 
1575</xsl:function>
1576
1577
1578<xsl:function name="functx:remove-elements" as="element()*" 
1579              xmlns:functx="http://www.functx.com" >
1580  <xsl:param name="elements" as="element()*"/> 
1581  <xsl:param name="names" as="xs:string*"/> 
1582 
1583   <xsl:for-each select="$elements">
1584     <xsl:element name="{node-name(.)}">
1585       <xsl:sequence select="(@*,
1586      node()[not(functx:name-test(name(),$names))])"/>
1587     </xsl:element>
1588   </xsl:for-each>
1589 
1590</xsl:function>
1591
1592
1593<xsl:function name="functx:repeat-string" as="xs:string" 
1594              xmlns:functx="http://www.functx.com" >
1595  <xsl:param name="stringToRepeat" as="xs:string?"/> 
1596  <xsl:param name="count" as="xs:integer"/> 
1597 
1598  <xsl:sequence select="
1599   string-join((for $i in 1 to $count return $stringToRepeat),
1600                        '')
1601 "/>
1602   
1603</xsl:function>
1604
1605
1606<xsl:function name="functx:replace-beginning" as="xs:string" 
1607              xmlns:functx="http://www.functx.com" >
1608  <xsl:param name="arg" as="xs:string?"/> 
1609  <xsl:param name="pattern" as="xs:string"/> 
1610  <xsl:param name="replacement" as="xs:string"/> 
1611 
1612  <xsl:sequence select="
1613   replace($arg, concat('^.*?', $pattern), $replacement)
1614 "/>
1615   
1616</xsl:function>
1617
1618
1619<xsl:function name="functx:replace-element-values" as="element()*" 
1620              xmlns:functx="http://www.functx.com" >
1621  <xsl:param name="elements" as="element()*"/> 
1622  <xsl:param name="values" as="xs:anyAtomicType*"/> 
1623 
1624   <xsl:for-each select="$elements">
1625     <xsl:variable name="seq" select="position()"/>
1626     <xsl:element name="{node-name(.)}">
1627       <xsl:sequence select="@*, $values[$seq]"/>
1628     </xsl:element>
1629   </xsl:for-each>
1630 
1631</xsl:function>
1632
1633
1634<xsl:function name="functx:replace-first" as="xs:string" 
1635              xmlns:functx="http://www.functx.com" >
1636  <xsl:param name="arg" as="xs:string?"/> 
1637  <xsl:param name="pattern" as="xs:string"/> 
1638  <xsl:param name="replacement" as="xs:string"/> 
1639 
1640  <xsl:sequence select="
1641   replace($arg, concat('(^.*?)', $pattern),
1642             concat('$1',$replacement))
1643 "/>
1644   
1645</xsl:function>
1646
1647
1648<xsl:function name="functx:replace-multi" as="xs:string?" 
1649              xmlns:functx="http://www.functx.com" >
1650  <xsl:param name="arg" as="xs:string?"/> 
1651  <xsl:param name="changeFrom" as="xs:string*"/> 
1652  <xsl:param name="changeTo" as="xs:string*"/> 
1653 
1654  <xsl:sequence select="
1655   if (count($changeFrom) > 0)
1656   then functx:replace-multi(
1657          replace($arg, $changeFrom[1],
1658                     functx:if-absent($changeTo[1],'')),
1659          $changeFrom[position() > 1],
1660          $changeTo[position() > 1])
1661   else $arg
1662 "/>
1663   
1664</xsl:function>
1665
1666
1667<xsl:function name="functx:reverse-string" as="xs:string" 
1668              xmlns:functx="http://www.functx.com" >
1669  <xsl:param name="arg" as="xs:string?"/> 
1670 
1671  <xsl:sequence select="
1672   codepoints-to-string(reverse(string-to-codepoints($arg)))
1673 "/>
1674   
1675</xsl:function>
1676
1677
1678<xsl:function name="functx:right-trim" as="xs:string" 
1679              xmlns:functx="http://www.functx.com" >
1680  <xsl:param name="arg" as="xs:string?"/> 
1681 
1682  <xsl:sequence select="
1683   replace($arg,'\s+$','')
1684 "/>
1685   
1686</xsl:function>
1687
1688
1689<xsl:function name="functx:scheme-from-uri" as="xs:string?" 
1690              xmlns:functx="http://www.functx.com" >
1691  <xsl:param name="uri" as="xs:string?"/> 
1692 
1693  <xsl:sequence select="
1694   substring-before($uri,':')
1695 "/>
1696   
1697</xsl:function>
1698
1699
1700<xsl:function name="functx:sequence-deep-equal" as="xs:boolean" 
1701              xmlns:functx="http://www.functx.com" >
1702  <xsl:param name="seq1" as="item()*"/> 
1703  <xsl:param name="seq2" as="item()*"/> 
1704 
1705  <xsl:sequence select="
1706  every $i in 1 to max((count($seq1),count($seq2)))
1707  satisfies deep-equal($seq1[$i],$seq2[$i])
1708 "/>
1709   
1710</xsl:function>
1711
1712
1713<xsl:function name="functx:sequence-node-equal-any-order" as="xs:boolean" 
1714              xmlns:functx="http://www.functx.com" >
1715  <xsl:param name="seq1" as="node()*"/> 
1716  <xsl:param name="seq2" as="node()*"/> 
1717 
1718  <xsl:sequence select="
1719  not( ($seq1 except $seq2, $seq2 except $seq1))
1720 "/>
1721   
1722</xsl:function>
1723
1724
1725<xsl:function name="functx:sequence-node-equal" as="xs:boolean" 
1726              xmlns:functx="http://www.functx.com" >
1727  <xsl:param name="seq1" as="node()*"/> 
1728  <xsl:param name="seq2" as="node()*"/> 
1729 
1730  <xsl:sequence select="
1731  every $i in 1 to max((count($seq1),count($seq2)))
1732  satisfies $seq1[$i] is $seq2[$i]
1733 "/>
1734   
1735</xsl:function>
1736
1737
1738<xsl:function name="functx:sequence-type" as="xs:string" 
1739              xmlns:functx="http://www.functx.com" >
1740  <xsl:param name="items" as="item()*"/> 
1741 
1742  <xsl:sequence select="
1743concat(
1744  if (empty($items))
1745  then 'empty-sequence()'
1746  else if (every $val in $items
1747           satisfies $val instance of xs:anyAtomicType)
1748  then if (count(distinct-values(functx:atomic-type($items)))
1749           > 1)
1750  then 'xs:anyAtomicType'
1751  else functx:atomic-type($items[1])
1752  else if (some $val in $items
1753           satisfies $val instance of xs:anyAtomicType)
1754  then 'item()'
1755  else if (count(distinct-values(functx:node-kind($items))) > 1)
1756  then 'node()'
1757  else concat(functx:node-kind($items[1]),'()')
1758  ,
1759  if (count($items) > 1)
1760  then '+' else '')
1761   "/>
1762   
1763</xsl:function>
1764
1765
1766<xsl:function name="functx:siblings-same-name" as="element()*" 
1767              xmlns:functx="http://www.functx.com" >
1768  <xsl:param name="element" as="element()?"/> 
1769 
1770  <xsl:sequence select="
1771   $element/../*[node-name(.) = node-name($element)]
1772   except $element
1773 "/>
1774   
1775</xsl:function>
1776
1777
1778<xsl:function name="functx:siblings" as="node()*" 
1779              xmlns:functx="http://www.functx.com" >
1780  <xsl:param name="node" as="node()?"/> 
1781 
1782  <xsl:sequence select="
1783   $node/../node() except $node
1784 "/>
1785   
1786</xsl:function>
1787
1788
1789<xsl:function name="functx:sort-as-numeric" as="item()*" 
1790              xmlns:functx="http://www.functx.com" >
1791  <xsl:param name="seq" as="item()*"/> 
1792 
1793   <xsl:for-each select="$seq">
1794     <xsl:sort select="number(.)"/>
1795     <xsl:copy-of select="."/>
1796   </xsl:for-each>
1797 
1798</xsl:function>
1799
1800
1801<xsl:function name="functx:sort-case-insensitive" as="item()*" 
1802              xmlns:functx="http://www.functx.com" >
1803  <xsl:param name="seq" as="item()*"/> 
1804 
1805   <xsl:for-each select="$seq">
1806     <xsl:sort select="upper-case(string(.))"/>
1807     <xsl:copy-of select="."/>
1808   </xsl:for-each>
1809 
1810</xsl:function>
1811
1812
1813<xsl:function name="functx:sort-document-order" as="node()*" 
1814              xmlns:functx="http://www.functx.com" >
1815  <xsl:param name="seq" as="node()*"/> 
1816 
1817  <xsl:sequence select="
1818   $seq/.
1819 "/>
1820   
1821</xsl:function>
1822
1823
1824<xsl:function name="functx:sort" as="item()*" 
1825              xmlns:functx="http://www.functx.com" >
1826  <xsl:param name="seq" as="item()*"/> 
1827 
1828   <xsl:for-each select="$seq">
1829     <xsl:sort select="."/>
1830     <xsl:copy-of select="."/>
1831   </xsl:for-each>
1832 
1833</xsl:function>
1834
1835
1836<xsl:function name="functx:substring-after-if-contains" as="xs:string?" 
1837              xmlns:functx="http://www.functx.com" >
1838  <xsl:param name="arg" as="xs:string?"/> 
1839  <xsl:param name="delim" as="xs:string"/> 
1840 
1841  <xsl:sequence select="
1842   if (contains($arg,$delim))
1843   then substring-after($arg,$delim)
1844   else $arg
1845 "/>
1846   
1847</xsl:function>
1848
1849
1850<xsl:function name="functx:substring-after-last-match" as="xs:string" 
1851              xmlns:functx="http://www.functx.com" >
1852  <xsl:param name="arg" as="xs:string?"/> 
1853  <xsl:param name="regex" as="xs:string"/> 
1854 
1855  <xsl:sequence select="
1856   replace($arg,concat('^.*',$regex),'')
1857 "/>
1858   
1859</xsl:function>
1860
1861
1862<xsl:function name="functx:substring-after-last" as="xs:string" 
1863              xmlns:functx="http://www.functx.com" >
1864  <xsl:param name="arg" as="xs:string?"/> 
1865  <xsl:param name="delim" as="xs:string"/> 
1866 
1867  <xsl:sequence select="
1868   replace ($arg,concat('^.*',functx:escape-for-regex($delim)),'')
1869 "/>
1870   
1871</xsl:function>
1872
1873
1874<xsl:function name="functx:substring-after-match" as="xs:string?" 
1875              xmlns:functx="http://www.functx.com" >
1876  <xsl:param name="arg" as="xs:string?"/> 
1877  <xsl:param name="regex" as="xs:string"/> 
1878 
1879  <xsl:sequence select="
1880   replace($arg,concat('^.*?',$regex),'')
1881 "/>
1882   
1883</xsl:function>
1884
1885
1886<xsl:function name="functx:substring-before-if-contains" as="xs:string?" 
1887              xmlns:functx="http://www.functx.com" >
1888  <xsl:param name="arg" as="xs:string?"/> 
1889  <xsl:param name="delim" as="xs:string"/> 
1890 
1891  <xsl:sequence select="
1892   if (contains($arg,$delim))
1893   then substring-before($arg,$delim)
1894   else $arg
1895 "/>
1896   
1897</xsl:function>
1898
1899
1900<xsl:function name="functx:substring-before-last-match" as="xs:string?" 
1901              xmlns:functx="http://www.functx.com" >
1902  <xsl:param name="arg" as="xs:string?"/> 
1903  <xsl:param name="regex" as="xs:string"/> 
1904 
1905  <xsl:sequence select="
1906   replace($arg,concat('^(.*)',$regex,'.*'),'$1')
1907 "/>
1908   
1909</xsl:function>
1910
1911
1912<xsl:function name="functx:substring-before-last" as="xs:string" 
1913              xmlns:functx="http://www.functx.com" >
1914  <xsl:param name="arg" as="xs:string?"/> 
1915  <xsl:param name="delim" as="xs:string"/> 
1916 
1917  <xsl:sequence select="
1918   if (matches($arg, functx:escape-for-regex($delim)))
1919   then replace($arg,
1920            concat('^(.*)', functx:escape-for-regex($delim),'.*'),
1921            '$1')
1922   else ''
1923 "/>
1924   
1925</xsl:function>
1926
1927
1928<xsl:function name="functx:substring-before-match" as="xs:string" 
1929              xmlns:functx="http://www.functx.com" >
1930  <xsl:param name="arg" as="xs:string?"/> 
1931  <xsl:param name="regex" as="xs:string"/> 
1932 
1933  <xsl:sequence select="
1934   tokenize($arg,$regex)[1]
1935 "/>
1936   
1937</xsl:function>
1938
1939
1940<xsl:function name="functx:time" as="xs:time" 
1941              xmlns:functx="http://www.functx.com" >
1942  <xsl:param name="hour" as="xs:anyAtomicType"/> 
1943  <xsl:param name="minute" as="xs:anyAtomicType"/> 
1944  <xsl:param name="second" as="xs:anyAtomicType"/> 
1945 
1946  <xsl:sequence select="
1947   xs:time(
1948     concat(
1949       functx:pad-integer-to-length(xs:integer($hour),2),':',
1950       functx:pad-integer-to-length(xs:integer($minute),2),':',
1951       functx:pad-integer-to-length(xs:integer($second),2)))
1952 "/>
1953   
1954</xsl:function>
1955
1956
1957<xsl:function name="functx:timezone-from-duration" as="xs:string" 
1958              xmlns:functx="http://www.functx.com" >
1959  <xsl:param name="duration" as="xs:dayTimeDuration"/> 
1960 
1961  <xsl:sequence select="
1962   if (string($duration) = ('PT0S','-PT0S'))
1963   then 'Z'
1964   else if (matches(string($duration),'-PT[1-9]H'))
1965   then replace(string($duration),'PT([1-9])H','0$1:00')
1966   else if (matches(string($duration),'PT[1-9]H'))
1967   then replace(string($duration),'PT([1-9])H','+0$1:00')
1968   else if (matches(string($duration),'-PT1[0-4]H'))
1969   then replace(string($duration),'PT(1[0-4])H','$1:00')
1970   else if (matches(string($duration),'PT1[0-4]H'))
1971   then replace(string($duration),'PT(1[0-4])H','+$1:00')
1972   else error(xs:QName('functx:Invalid_Duration_Value'))
1973 "/>
1974   
1975</xsl:function>
1976
1977
1978<xsl:function name="functx:total-days-from-duration" as="xs:decimal?" 
1979              xmlns:functx="http://www.functx.com" >
1980  <xsl:param name="duration" as="xs:dayTimeDuration?"/> 
1981 
1982  <xsl:sequence select="
1983   $duration div xs:dayTimeDuration('P1D')
1984 "/>
1985   
1986</xsl:function>
1987
1988
1989<xsl:function name="functx:total-hours-from-duration" as="xs:decimal?" 
1990              xmlns:functx="http://www.functx.com" >
1991  <xsl:param name="duration" as="xs:dayTimeDuration?"/> 
1992 
1993  <xsl:sequence select="
1994   $duration div xs:dayTimeDuration('PT1H')
1995 "/>
1996   
1997</xsl:function>
1998
1999
2000<xsl:function name="functx:total-minutes-from-duration" as="xs:decimal?" 
2001              xmlns:functx="http://www.functx.com" >
2002  <xsl:param name="duration" as="xs:dayTimeDuration?"/> 
2003 
2004  <xsl:sequence select="
2005   $duration div xs:dayTimeDuration('PT1M')
2006 "/>
2007   
2008</xsl:function>
2009
2010
2011<xsl:function name="functx:total-months-from-duration" as="xs:decimal?" 
2012              xmlns:functx="http://www.functx.com" >
2013  <xsl:param name="duration" as="xs:yearMonthDuration?"/> 
2014 
2015  <xsl:sequence select="
2016   $duration div xs:yearMonthDuration('P1M')
2017 "/>
2018   
2019</xsl:function>
2020
2021
2022<xsl:function name="functx:total-seconds-from-duration" as="xs:decimal?" 
2023              xmlns:functx="http://www.functx.com" >
2024  <xsl:param name="duration" as="xs:dayTimeDuration?"/> 
2025 
2026  <xsl:sequence select="
2027   $duration div xs:dayTimeDuration('PT1S')
2028 "/>
2029   
2030</xsl:function>
2031
2032
2033<xsl:function name="functx:total-years-from-duration" as="xs:decimal?" 
2034              xmlns:functx="http://www.functx.com" >
2035  <xsl:param name="duration" as="xs:yearMonthDuration?"/> 
2036 
2037  <xsl:sequence select="
2038   $duration div xs:yearMonthDuration('P1Y')
2039 "/>
2040   
2041</xsl:function>
2042
2043
2044<xsl:function name="functx:trim" as="xs:string" 
2045              xmlns:functx="http://www.functx.com" >
2046  <xsl:param name="arg" as="xs:string?"/> 
2047 
2048  <xsl:sequence select="
2049   replace(replace($arg,'\s+$',''),'^\s+','')
2050 "/>
2051   
2052</xsl:function>
2053
2054
2055<xsl:function name="functx:update-attributes" as="element()?" 
2056              xmlns:functx="http://www.functx.com" >
2057  <xsl:param name="elements" as="element()*"/> 
2058  <xsl:param name="attrNames" as="xs:QName*"/> 
2059  <xsl:param name="attrValues" as="xs:anyAtomicType*"/> 
2060 
2061  <xsl:for-each select="$elements">
2062    <xsl:variable name="element" select="."/>
2063    <xsl:copy>
2064      <xsl:for-each select="$attrNames">
2065        <xsl:variable name="seq" select="position()"/>
2066        <xsl:if test="$element/@*[node-name(.) = current()]">
2067          <xsl:attribute name="{.}"
2068                         namespace="{namespace-uri-from-QName(.)}"
2069                         select="$attrValues[$seq]"/>
2070        </xsl:if>
2071      </xsl:for-each>
2072      <xsl:copy-of select="@*[not(node-name(.) = $attrNames)]|node()"/>
2073    </xsl:copy>
2074  </xsl:for-each>
2075 
2076</xsl:function>
2077
2078
2079<xsl:function name="functx:value-except" as="xs:anyAtomicType*" 
2080              xmlns:functx="http://www.functx.com" >
2081  <xsl:param name="arg1" as="xs:anyAtomicType*"/> 
2082  <xsl:param name="arg2" as="xs:anyAtomicType*"/> 
2083 
2084  <xsl:sequence select="
2085  distinct-values($arg1[not(.=$arg2)])
2086 "/>
2087   
2088</xsl:function>
2089
2090
2091<xsl:function name="functx:value-intersect" as="xs:anyAtomicType*" 
2092              xmlns:functx="http://www.functx.com" >
2093  <xsl:param name="arg1" as="xs:anyAtomicType*"/> 
2094  <xsl:param name="arg2" as="xs:anyAtomicType*"/> 
2095 
2096  <xsl:sequence select="
2097  distinct-values($arg1[.=$arg2])
2098 "/>
2099   
2100</xsl:function>
2101
2102
2103<xsl:function name="functx:value-union" as="xs:anyAtomicType*" 
2104              xmlns:functx="http://www.functx.com" >
2105  <xsl:param name="arg1" as="xs:anyAtomicType*"/> 
2106  <xsl:param name="arg2" as="xs:anyAtomicType*"/> 
2107 
2108  <xsl:sequence select="
2109  distinct-values(($arg1, $arg2))
2110 "/>
2111   
2112</xsl:function>
2113
2114
2115<xsl:function name="functx:word-count" as="xs:integer" 
2116              xmlns:functx="http://www.functx.com" >
2117  <xsl:param name="arg" as="xs:string?"/> 
2118 
2119  <xsl:sequence select="
2120   count(tokenize($arg, '\W+')[. != ''])
2121 "/>
2122   
2123</xsl:function>
2124
2125
2126<xsl:function name="functx:words-to-camel-case" as="xs:string" 
2127              xmlns:functx="http://www.functx.com" >
2128  <xsl:param name="arg" as="xs:string?"/> 
2129 
2130  <xsl:sequence select="
2131     string-join((tokenize($arg,'\s+')[1],
2132       for $word in tokenize($arg,'\s+')[position() > 1]
2133       return functx:capitalize-first($word))
2134      ,'')
2135 "/>
2136   
2137</xsl:function>
2138
2139
2140<xsl:function name="functx:wrap-values-in-elements" as="element()*" 
2141              xmlns:functx="http://www.functx.com" >
2142  <xsl:param name="values" as="xs:anyAtomicType*"/> 
2143  <xsl:param name="elementName" as="xs:QName"/> 
2144 
2145   <xsl:for-each select="$values">
2146     <xsl:element name="{$elementName}"
2147                  namespace="{namespace-uri-from-QName($elementName)}">
2148       <xsl:sequence select="."/>
2149     </xsl:element>
2150   </xsl:for-each>
2151 
2152</xsl:function>
2153
2154
2155<xsl:function name="functx:yearMonthDuration" as="xs:yearMonthDuration" 
2156              xmlns:functx="http://www.functx.com" >
2157  <xsl:param name="years" as="xs:decimal?"/> 
2158  <xsl:param name="months" as="xs:integer?"/> 
2159 
2160  <xsl:sequence select="
2161    (xs:yearMonthDuration('P1M') * functx:if-empty($months,0)) +
2162    (xs:yearMonthDuration('P1Y') * functx:if-empty($years,0))
2163 "/>
2164   
2165</xsl:function>
2166
2167
2168</xsl:stylesheet>
Note: See TracBrowser for help on using the repository browser.