]> git.stg.codes - stg.git/blob - doc/xslt/slides/keynote/xsltsl/uri.xsl
Infer DST from the current locale for mktime.
[stg.git] / doc / xslt / slides / keynote / xsltsl / uri.xsl
1 <?xml version="1.0"?>
2
3 <xsl:stylesheet
4   version="1.0"
5   extension-element-prefixes="doc"
6   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
7   xmlns:doc="http://xsltsl.org/xsl/documentation/1.0"
8   xmlns:uri="http://xsltsl.org/uri"
9 >
10
11   <doc:reference xmlns="">
12     <referenceinfo>
13       <releaseinfo role="meta">
14         $Id: uri.xsl 3991 2004-11-10 06:51:55Z balls $
15       </releaseinfo>
16       <author>
17         <surname>Diamond</surname>
18         <firstname>Jason</firstname>
19       </author>
20       <copyright>
21         <year>2001</year>
22         <holder>Jason Diamond</holder>
23       </copyright>
24     </referenceinfo>
25
26     <title>URI (Uniform Resource Identifier) Processing</title>
27
28     <partintro>
29       <section>
30         <title>Introduction</title>
31         <para>This module provides templates for processing URIs (Uniform Resource Identifers).</para>
32       </section>
33     </partintro>
34
35   </doc:reference>
36
37   <doc:template name="uri:is-absolute-uri" xmlns="">
38     <refpurpose>Determines if a URI is absolute or relative.</refpurpose>
39
40     <refdescription>
41       <para>Absolute URIs start with a scheme (like "http:" or "mailto:").</para>
42     </refdescription>
43
44     <refparameter>
45       <variablelist>
46         <varlistentry>
47           <term>uri</term>
48           <listitem>
49             <para>An absolute or relative URI.</para>
50           </listitem>
51         </varlistentry>
52       </variablelist>
53     </refparameter>
54
55     <refreturn>
56       <para>Returns 'true' if the URI is absolute or '' if it's not.</para>
57     </refreturn>
58   </doc:template>
59
60   <xsl:template name="uri:is-absolute-uri">
61     <xsl:param name="uri"/>
62
63     <xsl:if test="contains($uri, ':')">
64       <xsl:value-of select="true()"/>
65     </xsl:if>
66
67   </xsl:template>
68
69   <doc:template name="uri:get-uri-scheme" xmlns="">
70     <refpurpose>Gets the scheme part of a URI.</refpurpose>
71
72     <refdescription>
73       <para>The ':' is not part of the scheme.</para>
74     </refdescription>
75
76     <refparameter>
77       <variablelist>
78         <varlistentry>
79           <term>uri</term>
80           <listitem>
81             <para>An absolute or relative URI.</para>
82           </listitem>
83         </varlistentry>
84       </variablelist>
85     </refparameter>
86
87     <refreturn>
88       <para>Returns the scheme (without the ':') or '' if the URI is relative.</para>
89     </refreturn>
90   </doc:template>
91
92   <xsl:template name="uri:get-uri-scheme">
93     <xsl:param name="uri"/>
94     <xsl:if test="contains($uri, ':')">
95       <xsl:value-of select="substring-before($uri, ':')"/>
96     </xsl:if>
97   </xsl:template>
98
99   <doc:template name="uri:get-uri-authority" xmlns="">
100     <refpurpose>Gets the authority part of a URI.</refpurpose>
101
102     <refdescription>
103       <para>The authority usually specifies the host machine for a resource. It always follows '//' in a typical URI.</para>
104     </refdescription>
105
106     <refparameter>
107       <variablelist>
108         <varlistentry>
109           <term>uri</term>
110           <listitem>
111             <para>An absolute or relative URI.</para>
112           </listitem>
113         </varlistentry>
114       </variablelist>
115     </refparameter>
116
117     <refreturn>
118       <para>Returns the authority (without the '//') or '' if the URI has no authority.</para>
119     </refreturn>
120   </doc:template>
121
122   <xsl:template name="uri:get-uri-authority">
123     <xsl:param name="uri"/>
124
125     <xsl:variable name="a">
126       <xsl:choose>
127         <xsl:when test="contains($uri, ':')">
128           <xsl:if test="substring(substring-after($uri, ':'), 1, 2) = '//'">
129               <xsl:value-of select="substring(substring-after($uri, ':'), 3)"/>
130           </xsl:if>
131         </xsl:when>
132         <xsl:otherwise>
133           <xsl:if test="substring($uri, 1, 2) = '//'">
134             <xsl:value-of select="substring($uri, 3)"/>
135           </xsl:if>
136         </xsl:otherwise>
137       </xsl:choose>
138     </xsl:variable>
139
140     <xsl:choose>
141       <xsl:when test="contains($a, '/')">
142         <xsl:value-of select="substring-before($a, '/')" />
143       </xsl:when>
144       <xsl:when test="contains($a, '?')">
145         <xsl:value-of select="substring-before($a, '?')" />
146       </xsl:when>
147       <xsl:when test="contains($a, '#')">
148         <xsl:value-of select="substring-before($a, '#')" />
149       </xsl:when>
150       <xsl:otherwise>
151         <xsl:value-of select="$a" />
152       </xsl:otherwise>
153     </xsl:choose>
154
155   </xsl:template>
156
157   <doc:template name="uri:get-uri-path" xmlns="">
158     <refpurpose>Gets the path part of a URI.</refpurpose>
159
160     <refdescription>
161       <para>The path usually comes after the '/' in a URI.</para>
162     </refdescription>
163
164     <refparameter>
165       <variablelist>
166         <varlistentry>
167           <term>uri</term>
168           <listitem>
169             <para>An absolute or relative URI.</para>
170           </listitem>
171         </varlistentry>
172       </variablelist>
173     </refparameter>
174
175     <refreturn>
176       <para>Returns the path (with any leading '/') or '' if the URI has no path.</para>
177     </refreturn>
178   </doc:template>
179
180   <xsl:template name="uri:get-uri-path">
181     <xsl:param name="uri"/>
182
183     <xsl:variable name="p">
184       <xsl:choose>
185         <xsl:when test="contains($uri, '//')">
186           <xsl:if test="contains(substring-after($uri, '//'), '/')">
187             <xsl:value-of select="concat('/', substring-after(substring-after($uri, '//'), '/'))"/>
188           </xsl:if>
189         </xsl:when>
190         <xsl:otherwise>
191           <xsl:choose>
192             <xsl:when test="contains($uri, ':')">
193               <xsl:value-of select="substring-after($uri, ':')"/>
194             </xsl:when>
195             <xsl:otherwise>
196               <xsl:value-of select="$uri"/>
197             </xsl:otherwise>
198           </xsl:choose>
199         </xsl:otherwise>
200       </xsl:choose>
201     </xsl:variable>
202
203     <xsl:choose>
204       <xsl:when test="contains($p, '?')">
205         <xsl:value-of select="substring-before($p, '?')" />
206       </xsl:when>
207       <xsl:when test="contains($p, '#')">
208         <xsl:value-of select="substring-before($p, '#')" />
209       </xsl:when>
210       <xsl:otherwise>
211         <xsl:value-of select="$p" />
212       </xsl:otherwise>
213     </xsl:choose>
214
215   </xsl:template>
216
217   <doc:template name="uri:get-uri-query" xmlns="">
218     <refpurpose>Gets the query part of a URI.</refpurpose>
219
220     <refdescription>
221       <para>The query comes after the '?' in a URI.</para>
222     </refdescription>
223
224     <refparameter>
225       <variablelist>
226         <varlistentry>
227           <term>uri</term>
228           <listitem>
229             <para>An absolute or relative URI.</para>
230           </listitem>
231         </varlistentry>
232       </variablelist>
233     </refparameter>
234
235     <refreturn>
236       <para>Returns the query (without the '?') or '' if the URI has no query.</para>
237     </refreturn>
238   </doc:template>
239
240   <xsl:template name="uri:get-uri-query">
241     <xsl:param name="uri"/>
242
243     <xsl:variable name="q" select="substring-after($uri, '?')"/>
244
245     <xsl:choose>
246       <xsl:when test="contains($q, '#')">
247         <xsl:value-of select="substring-before($q, '#')"/>
248       </xsl:when>
249       <xsl:otherwise><xsl:value-of select="$q"/></xsl:otherwise>
250     </xsl:choose>
251
252   </xsl:template>
253
254   <doc:template name="uri:get-uri-fragment" xmlns="">
255     <refpurpose>Gets the fragment part of a URI.</refpurpose>
256
257     <refdescription>
258       <para>The fragment comes after the '#' in a URI.</para>
259     </refdescription>
260
261     <refparameter>
262       <variablelist>
263         <varlistentry>
264           <term>uri</term>
265           <listitem>
266             <para>An absolute or relative URI.</para>
267           </listitem>
268         </varlistentry>
269       </variablelist>
270     </refparameter>
271
272     <refreturn>
273       <para>Returns the fragment (without the '#') or '' if the URI has no fragment.</para>
274     </refreturn>
275   </doc:template>
276
277   <xsl:template name="uri:get-uri-fragment">
278     <xsl:param name="uri"/>
279
280     <xsl:value-of select="substring-after($uri, '#')"/>
281
282   </xsl:template>
283
284   <doc:template name="uri:resolve-uri" xmlns="">
285     <refpurpose>Resolves a URI reference against a base URI.</refpurpose>
286
287     <refdescription>
288       <para>This template follows the guidelines specified by <ulink url="ftp://ftp.isi.edu/in-notes/rfc2396.txt">RFC 2396</ulink>.</para>
289     </refdescription>
290
291     <refparameter>
292       <variablelist>
293         <varlistentry>
294           <term>reference</term>
295           <listitem>
296             <para>A (potentially relative) URI reference.</para>
297           </listitem>
298         </varlistentry>
299         <varlistentry>
300           <term>base</term>
301           <listitem>
302             <para>The base URI.</para>
303           </listitem>
304         </varlistentry>
305         <varlistentry>
306           <term>document</term>
307           <listitem>
308             <para>The URI of the current document. This defaults to the value of the base URI if not specified.</para>
309           </listitem>
310         </varlistentry>
311       </variablelist>
312     </refparameter>
313
314     <refreturn>
315       <para>The "combined" URI.</para>
316     </refreturn>
317   </doc:template>
318
319   <xsl:template name="uri:resolve-uri">
320     <xsl:param name="reference"/>
321     <xsl:param name="base"/>
322     <xsl:param name="document" select="$base"/>
323
324     <xsl:variable name="reference-scheme">
325       <xsl:call-template name="uri:get-uri-scheme">
326         <xsl:with-param name="uri" select="$reference"/>
327       </xsl:call-template>
328     </xsl:variable>
329
330     <xsl:variable name="reference-authority">
331       <xsl:call-template name="uri:get-uri-authority">
332         <xsl:with-param name="uri" select="$reference"/>
333       </xsl:call-template>
334     </xsl:variable>
335
336     <xsl:variable name="reference-path">
337       <xsl:call-template name="uri:get-uri-path">
338         <xsl:with-param name="uri" select="$reference"/>
339       </xsl:call-template>
340     </xsl:variable>
341
342     <xsl:variable name="reference-query">
343       <xsl:call-template name="uri:get-uri-query">
344         <xsl:with-param name="uri" select="$reference"/>
345       </xsl:call-template>
346     </xsl:variable>
347
348     <xsl:variable name="reference-fragment">
349       <xsl:call-template name="uri:get-uri-fragment">
350         <xsl:with-param name="uri" select="$reference"/>
351       </xsl:call-template>
352     </xsl:variable>
353
354     <xsl:choose>
355
356       <xsl:when test="
357         not(string-length($reference-scheme)) and
358         not(string-length($reference-authority)) and
359         not(string-length($reference-path)) and
360         not(string-length($reference-query))"
361       >
362
363         <xsl:choose>
364           <xsl:when test="contains($document, '?')">
365             <xsl:value-of select="substring-before($document, '?')"/>
366           </xsl:when>
367           <xsl:when test="contains($document, '#')">
368             <xsl:value-of select="substring-before($document, '#')"/>
369           </xsl:when>
370           <xsl:otherwise>
371             <xsl:value-of select="$document"/>
372           </xsl:otherwise>
373         </xsl:choose>
374
375         <xsl:if test="string-length($reference-fragment)">
376           <xsl:value-of select="concat('#', $reference-fragment)"/>
377         </xsl:if>
378
379       </xsl:when>
380
381       <xsl:when test="string-length($reference-scheme)">
382
383         <xsl:value-of select="$reference"/>
384
385       </xsl:when>
386
387       <xsl:otherwise>
388
389         <xsl:variable name="base-scheme">
390           <xsl:call-template name="uri:get-uri-scheme">
391             <xsl:with-param name="uri" select="$base"/>
392           </xsl:call-template>
393         </xsl:variable>
394
395         <xsl:variable name="base-authority">
396           <xsl:call-template name="uri:get-uri-authority">
397             <xsl:with-param name="uri" select="$base"/>
398           </xsl:call-template>
399         </xsl:variable>
400
401         <xsl:variable name="base-path">
402           <xsl:call-template name="uri:get-uri-path">
403             <xsl:with-param name="uri" select="$base"/>
404           </xsl:call-template>
405         </xsl:variable>
406
407         <xsl:variable name="base-query">
408           <xsl:call-template name="uri:get-uri-query">
409             <xsl:with-param name="uri" select="$base"/>
410           </xsl:call-template>
411         </xsl:variable>
412
413         <xsl:variable name="base-fragment">
414           <xsl:call-template name="uri:get-uri-fragment">
415             <xsl:with-param name="uri" select="$base"/>
416           </xsl:call-template>
417         </xsl:variable>
418
419         <xsl:variable name="result-authority">
420           <xsl:choose>
421             <xsl:when test="string-length($reference-authority)">
422               <xsl:value-of select="$reference-authority"/>
423             </xsl:when>
424             <xsl:otherwise>
425               <xsl:value-of select="$base-authority"/>
426             </xsl:otherwise>
427           </xsl:choose>
428         </xsl:variable>
429
430         <xsl:variable name="result-path">
431           <xsl:choose>
432             <!-- don't normalize absolute paths -->
433             <xsl:when test="starts-with($reference-path, '/')">
434               <xsl:value-of select="$reference-path" />
435             </xsl:when>
436             <xsl:otherwise>
437               <xsl:call-template name="uri:normalize-path">
438                 <xsl:with-param name="path">
439                   <xsl:if test="string-length($reference-authority) = 0 and substring($reference-path, 1, 1) != '/'">
440                     <xsl:call-template name="uri:get-path-without-file">
441                       <xsl:with-param name="path-with-file" select="$base-path"/>
442                     </xsl:call-template>
443                     <xsl:value-of select="'/'"/>
444                   </xsl:if>
445                   <xsl:value-of select="$reference-path"/>
446                 </xsl:with-param>
447               </xsl:call-template>
448             </xsl:otherwise>
449           </xsl:choose>
450         </xsl:variable>
451
452         <xsl:value-of select="concat($base-scheme, '://', $result-authority, $result-path)"/>
453
454         <xsl:if test="string-length($reference-query)">
455           <xsl:value-of select="concat('?', $reference-query)"/>
456         </xsl:if>
457
458         <xsl:if test="string-length($reference-fragment)">
459           <xsl:value-of select="concat('#', $reference-fragment)"/>
460         </xsl:if>
461
462       </xsl:otherwise>
463     </xsl:choose>
464
465   </xsl:template>
466
467   <xsl:template name="uri:get-path-without-file">
468     <xsl:param name="path-with-file" />
469     <xsl:param name="path-without-file" />
470
471     <xsl:choose>
472       <xsl:when test="contains($path-with-file, '/')">
473         <xsl:call-template name="uri:get-path-without-file">
474           <xsl:with-param name="path-with-file" select="substring-after($path-with-file, '/')" />
475           <xsl:with-param name="path-without-file">
476             <xsl:choose>
477               <xsl:when test="$path-without-file">
478                 <xsl:value-of select="concat($path-without-file, '/', substring-before($path-with-file, '/'))" />
479               </xsl:when>
480               <xsl:otherwise>
481                 <xsl:value-of select="substring-before($path-with-file, '/')" />
482               </xsl:otherwise>
483             </xsl:choose>
484           </xsl:with-param>
485         </xsl:call-template>
486       </xsl:when>
487       <xsl:otherwise>
488         <xsl:value-of select="$path-without-file" />
489       </xsl:otherwise>
490     </xsl:choose>
491
492   </xsl:template>
493
494   <xsl:template name="uri:normalize-path">
495     <xsl:param name="path"/>
496     <xsl:param name="result" select="''"/>
497
498     <xsl:choose>
499       <xsl:when test="string-length($path)">
500         <xsl:choose>
501           <xsl:when test="$path = '/'">
502             <xsl:value-of select="concat($result, '/')"/>
503           </xsl:when>
504           <xsl:when test="$path = '.'">
505             <xsl:value-of select="concat($result, '/')"/>
506           </xsl:when>
507           <xsl:when test="$path = '..'">
508             <xsl:call-template name="uri:get-path-without-file">
509               <xsl:with-param name="path-with-file" select="$result"/>
510             </xsl:call-template>
511             <xsl:value-of select="'/'"/>
512           </xsl:when>
513           <xsl:when test="contains($path, '/')">
514             <!-- the current segment -->
515             <xsl:variable name="s" select="substring-before($path, '/')"/>
516             <!-- the remaining path -->
517             <xsl:variable name="p">
518               <xsl:choose>
519                 <xsl:when test="substring-after($path, '/') = ''">
520                   <xsl:value-of select="'/'"/>
521                 </xsl:when>
522                 <xsl:otherwise>
523                   <xsl:value-of select="substring-after($path, '/')"/>
524                 </xsl:otherwise>
525               </xsl:choose>
526             </xsl:variable>
527             <xsl:choose>
528               <xsl:when test="$s = ''">
529                 <xsl:call-template name="uri:normalize-path">
530                   <xsl:with-param name="path" select="$p"/>
531                   <xsl:with-param name="result" select="$result"/>
532                 </xsl:call-template>
533               </xsl:when>
534               <xsl:when test="$s = '.'">
535                 <xsl:call-template name="uri:normalize-path">
536                   <xsl:with-param name="path" select="$p"/>
537                   <xsl:with-param name="result" select="$result"/>
538                 </xsl:call-template>
539               </xsl:when>
540               <xsl:when test="$s = '..'">
541                 <xsl:choose>
542                   <xsl:when test="string-length($result) and (substring($result, string-length($result) - 2) != '/..')">
543                     <xsl:call-template name="uri:normalize-path">
544                       <xsl:with-param name="path" select="$p"/>
545                       <xsl:with-param name="result">
546                         <xsl:call-template name="uri:get-path-without-file">
547                           <xsl:with-param name="path-with-file" select="$result"/>
548                         </xsl:call-template>
549                       </xsl:with-param>
550                     </xsl:call-template>
551                   </xsl:when>
552                   <xsl:otherwise>
553                     <xsl:call-template name="uri:normalize-path">
554                       <xsl:with-param name="path" select="$p"/>
555                       <xsl:with-param name="result" select="concat($result, '/..')"/>
556                     </xsl:call-template>
557                   </xsl:otherwise>
558                 </xsl:choose>
559               </xsl:when>
560               <xsl:otherwise>
561                 <xsl:call-template name="uri:normalize-path">
562                   <xsl:with-param name="path" select="$p"/>
563                   <xsl:with-param name="result" select="concat($result, '/', $s)"/>
564                 </xsl:call-template>
565               </xsl:otherwise>
566             </xsl:choose>
567           </xsl:when>
568           <xsl:otherwise>
569             <xsl:value-of select="concat($result, '/', $path)"/>
570           </xsl:otherwise>
571         </xsl:choose>
572       </xsl:when>
573       <xsl:otherwise>
574         <xsl:value-of select="$result"/>
575       </xsl:otherwise>
576     </xsl:choose>
577
578   </xsl:template>
579
580 </xsl:stylesheet>