Skip to content
Newer
Older
100644 328 lines (269 sloc) 9.65 KB
9a6bbf9 @defunkt hatom templates
authored Jan 21, 2008
1 <!-- -*- mode: indented-text;-*- -->
2 <xsl:transform
3 xmlns:xsl ="http://www.w3.org/1999/XSL/Transform" version="1.0"
4 xmlns:uri ="http://www.w3.org/2000/07/uri43/uri.xsl?template="
5 xmlns:html ="http://www.w3.org/1999/xhtml"
6 exclude-result-prefixes="uri html"
7 >
8
9 <div xmlns="http://www.w3.org/1999/xhtml">
10
11 <h2>Share and Enjoy</h2>
12
13 <p>$Id: uri.xsl,v 1.12 2004/11/05 10:35:03 dom Exp $</p>
14
15 <p>Copyright (c) 2000 W3C (MIT, INRIA, Keio), released under the <a
16 href="http://www.w3.org/Consortium/Legal/copyright-software-19980720">
17 W3C Open Source License</a> of August 14 1998. </p>
18
19 <h2>Reference</h2>
20
21 <p><cite><a href="http://www.ietf.org/rfc/rfc2396.txt">Uniform
22 Resource Identifiers (URI): Generic Syntax</a></cite> (RFC 2396)
23 T. Berners-Lee, R. Fielding, L. Masinter August 1998 </p>
24
25 </div>
26
27 <xsl:param name="Debug" select="0"/>
28
29 <xsl:variable name="uri:lowalpha"
30 select='"abcdefghijklmnopqrstuvwxyz"'/>
31 <xsl:variable name="uri:upalpha"
32 select='"ABCDEFGHIJKLMNOPQRSTUVWXYZ"'/>
33 <xsl:variable name="uri:digit"
34 select='"01234567890"'/>
35 <xsl:variable name="uri:alpha"
36 select='concat($uri:lowalpha, $uri:upalpha)'/>
37
38 <xsl:template name="uri:expand">
39 <!-- 5.2. Resolving Relative References to Absolute Form -->
40 <xsl:param name="base"/> <!-- an absolute URI -->
41 <xsl:param name="there"/> <!-- a URI reference -->
42
43 <!-- @@assert that $there contains only URI characters -->
44 <!-- @@implement the unicode->ascii thingy from HTML 4.0 -->
45
46 <xsl:variable name="fragment" select='substring-after($there, "#")'/>
47 <!-- hmm... I'd like to split after the *last* #,
48 but substring-after splits after the first occurence.
49 Anyway... more than one # is illegal -->
50
51 <xsl:variable name="hashFragment">
52 <xsl:choose>
53 <xsl:when test="string-length($fragment) > 0">
54 <xsl:value-of select='concat("#", $fragment)'/>
55 </xsl:when>
56 <xsl:otherwise>
57 <xsl:value-of select='""'/>
58 </xsl:otherwise>
59 </xsl:choose>
60 </xsl:variable>
61 <xsl:variable name="rest"
62 select='substring($there, 1,
63 string-length($there)
64 - string-length($hashFragment))'/>
65
66 <xsl:if test="$Debug"><xsl:message>
67 there: [<xsl:value-of select="$there"/>]
68 fragment: [<xsl:value-of select="$fragment"/>]
69 hashFragment: [<xsl:value-of select="$hashFragment"/>]
70 rest: [<xsl:value-of select="$rest"/>]
71 </xsl:message></xsl:if>
72
73 <xsl:choose>
74 <!-- step 2) -->
75 <xsl:when test="string-length($rest) = 0">
76 <xsl:if test="0">
77 <xsl:message>ur:expand called with reference to self-same document.
78 should this be prohibited? i.e.
79 should the caller handle references
80 to the self-same document?</xsl:message>
81 </xsl:if>
82 <xsl:value-of select="concat($base, $hashFragment)"/>
83 </xsl:when>
84
85 <xsl:otherwise>
86 <xsl:variable name="scheme">
87 <xsl:call-template name="uri:split-scheme">
88 <xsl:with-param name="ref" select="$rest"/>
89 </xsl:call-template>
90 </xsl:variable>
91
92 <xsl:choose>
93 <xsl:when test='string-length($scheme) > 0'>
94 <!-- step 3) ref is absolute. we're done -->
95 <xsl:value-of select="$there"/>
96 </xsl:when>
97 <xsl:when test="string-length($base) = 0">
98 <!-- if base is not an absoute uri, no point to continue processing -->
99 <xsl:message>base uri empty, defaulting to return there</xsl:message>
100 <xsl:value-of select="$there"/>
101 </xsl:when>
102 <xsl:otherwise>
103 <xsl:variable name="rest2"
104 select='substring($rest, string-length($scheme) + 1)'/>
105
106 <xsl:variable name="baseScheme">
107 <xsl:call-template name="uri:split-scheme">
108 <xsl:with-param name="ref" select="$base"/>
109 </xsl:call-template>
110 </xsl:variable>
111
112 <xsl:choose>
113 <xsl:when test='starts-with($rest2, "//")'>
114 <!-- step 4) network-path; we're done -->
115
116 <xsl:value-of select='concat($baseScheme, ":",
117 $rest2, $hashFragment)'/>
118 </xsl:when>
119
120 <xsl:otherwise>
121
122 <xsl:variable name="baseRest"
123 select='substring($base,
124 string-length($baseScheme) + 2)'/>
125
126 <xsl:variable name="baseAuthority">
127 <xsl:call-template name="uri:split-authority">
128 <xsl:with-param name="ref" select="$baseRest"/>
129 </xsl:call-template>
130 </xsl:variable>
131
132 <xsl:choose>
133 <xsl:when test='starts-with($rest2, "/")'>
134 <!-- step 5) absolute-path; we're done -->
135
136 <xsl:value-of select='concat($baseScheme, ":",
137 $baseAuthority,
138 $rest2, $hashFragment)'/>
139 </xsl:when>
140
141 <xsl:otherwise>
142 <!-- step 6) relative-path -->
143 <!-- @@ this part of the implementation is *NOT*
144 per the spec, because I want combine(wrt(x,y))=y
145 even in the case of y = foo/../bar
146 -->
147
148 <xsl:variable name="baseRest2"
149 select='substring($baseRest,
150 string-length($baseAuthority) + 1)'/>
151
152 <xsl:variable name="baseParent">
153 <xsl:call-template name="uri:path-parent">
154 <xsl:with-param name="path" select="$baseRest2"/>
155 </xsl:call-template>
156 </xsl:variable>
157
158 <xsl:variable name="path">
159 <xsl:call-template name="uri:follow-path">
160 <xsl:with-param name="start" select="$baseParent"/>
161 <xsl:with-param name="path" select="$rest2"/>
162 </xsl:call-template>
163 </xsl:variable>
164
165 <xsl:if test="$Debug"><xsl:message>
166 step 6 rel
167 rest2: [<xsl:value-of select="$rest2"/>]
168 baseRest2: [<xsl:value-of select="$baseRest2"/>]
169 baseParent: [<xsl:value-of select="$baseParent"/>]
170 path: [<xsl:value-of select="$path"/>]
171 </xsl:message></xsl:if>
172
173 <xsl:value-of select='concat($baseScheme, ":",
174 $baseAuthority,
175 $path,
176 $hashFragment)'/>
177 </xsl:otherwise>
178 </xsl:choose>
179 </xsl:otherwise>
180 </xsl:choose>
181
182 </xsl:otherwise>
183 </xsl:choose>
184 </xsl:otherwise>
185 </xsl:choose>
186 </xsl:template>
187
188
189 <xsl:template name="uri:split-scheme">
190 <!-- from a URI reference -->
191 <xsl:param name="ref"/>
192
193 <xsl:variable name="scheme_"
194 select='substring-before($ref, ":")'/>
195 <xsl:choose>
196 <!-- test whether $scheme_ is a legal scheme name,
197 i.e. whether it starts with an alpha
198 and contains only alpha, digit, +, -, .
199 -->
200 <xsl:when
201 test='string-length($scheme_) > 0
202 and contains($uri:alpha, substring($scheme_, 1, 1))
203 and string-length(translate(substring($scheme_, 2),
204 concat($uri:alpha, $uri:digit,
205 "+-."),
206 "")) = 0'>
207 <xsl:value-of select="$scheme_"/>
208 </xsl:when>
209
210 <xsl:otherwise>
211 <xsl:value-of select='""'/>
212 </xsl:otherwise>
213 </xsl:choose>
214 </xsl:template>
215
216
217 <xsl:template name="uri:split-authority">
218 <!-- from a URI reference that has had the fragment identifier
219 and scheme removed -->
220 <!-- cf 3.2. Authority Component -->
221
222 <xsl:param name="ref"/>
223
224 <xsl:choose>
225 <xsl:when test='starts-with($ref, "//")'>
226 <xsl:variable name="auth1" select='substring($ref, 3)'/>
227 <xsl:variable name="auth2">
228 <xsl:choose>
229 <xsl:when test='contains($auth1, "?")'>
230 <xsl:value-of select='substring-before($auth1, "?")'/>
231 </xsl:when>
232 <xsl:otherwise><xsl:value-of select="$auth1"/>
233 </xsl:otherwise>
234 </xsl:choose>
235 </xsl:variable>
236
237 <xsl:variable name="auth3">
238 <xsl:choose>
239 <xsl:when test='contains($auth2, "/")'>
240 <xsl:value-of select='substring-before($auth1, "/")'/>
241 </xsl:when>
242 <xsl:otherwise><xsl:value-of select="$auth2"/>
243 </xsl:otherwise>
244 </xsl:choose>
245 </xsl:variable>
246
247 <xsl:value-of select='concat("//", $auth3)'/>
248 </xsl:when>
249
250 <xsl:otherwise>
251 <xsl:value-of select='""'/>
252 </xsl:otherwise>
253 </xsl:choose>
254 </xsl:template>
255
256 <xsl:template name="uri:follow-path">
257 <xsl:param name="start"/> <!-- doesn't end with / ; may be empty -->
258 <xsl:param name="path"/> <!-- doesn't start with / -->
259
260 <xsl:if test="$Debug"><xsl:message>
261 follow-path
262 start: [<xsl:value-of select="$start"/>]
263 path: [<xsl:value-of select="$path"/>]
264 </xsl:message></xsl:if>
265
266 <xsl:choose>
267 <xsl:when test='starts-with($path, "./")'>
268 <xsl:call-template name="uri:follow-path">
269 <xsl:with-param name="start" select="$start"/>
270 <xsl:with-param name="path" select='substring($path, 3)'/>
271 </xsl:call-template>
272 </xsl:when>
273
274 <xsl:when test='starts-with($path, "../")'>
275 <xsl:call-template name="uri:follow-path">
276 <xsl:with-param name="start">
277 <xsl:call-template name="uri:path-parent">
278 <xsl:with-param name="path" select="$start"/>
279 </xsl:call-template>
280 </xsl:with-param>
281 <xsl:with-param name="path" select='substring($path, 4)'/>
282 </xsl:call-template>
283 </xsl:when>
284
285 <xsl:otherwise>
286 <xsl:value-of select='concat($start, "/", $path)'/>
287 </xsl:otherwise>
288 </xsl:choose>
289 </xsl:template>
290
291
292 <xsl:template name="uri:path-parent">
293 <xsl:param name="path"/>
294
295 <xsl:if test="$Debug"><xsl:message>
296 path parent
297 path: [<xsl:value-of select="$path"/>]
298 </xsl:message></xsl:if>
299
300 <xsl:choose>
301 <!-- foo/bar/ => foo/bar , return -->
302 <xsl:when test='substring($path, string-length($path)) = "/"'>
303 <xsl:value-of select='substring($path, 1, string-length($path)-1)'/>
304 </xsl:when>
305
306 <!-- foo/bar/baz => foo/bar/ba , recur -->
307 <!-- foo/bar/ba => foo/bar/b , recur -->
308 <!-- foo/bar/b => foo/bar/ , recur -->
309 <xsl:when test='contains($path, "/")'>
310 <xsl:call-template name="uri:path-parent">
311 <xsl:with-param name="path"
312 select='substring($path, 1, string-length($path)-1)'/>
313 </xsl:call-template>
314 </xsl:when>
315
316 <!-- '' => '' -->
317 <!-- foo => '' -->
318 <xsl:otherwise>
319 <xsl:value-of select='""'/>
320 </xsl:otherwise>
321
322 </xsl:choose>
323
324 </xsl:template>
325
326
327 </xsl:transform>
Something went wrong with that request. Please try again.