3 ;;; Examples of s-expression syntax for XSLT templates.
5 ;;; (Only <template> itself and its instructions so far.
6 ;;; Not sure yet about <stylesheet> and its top level elements.)
8 ;;; I'm using symbols in the XSL package here instead of keywords (but that
9 ;;; doesn't really matter).
11 ;;; There are currently no xsl:if/xsl:choose with XSLT semantics, only
12 ;;; the lisp-style forms if, when, unless, cond. We could add the xsl:
13 ;;; forms if users want them, since XSL doesn't import CL anymore.
15 ;;; The tricky part are forms with multiple different kinds of optional
16 ;;; stuff, like xsl:template which has both normal attributes, AND
17 ;;; parameters AND a body. Or xsl:apply-templates with normal attributes AND
18 ;;; parameters AND sorting rules. I think body and parameters should
19 ;;; have a syntax and is particularly easy to use, whereas sorting rules
20 ;;; are probably less common.
22 ;;; FIXME: How can we distinguish between:
23 ;;; (i) a pre-parsed XPath expression
24 ;;; (ii) an XPath string (for example, in <xsl:variable select="foo"/>)
25 ;;; (iii) an XSLT fragment (for example, in <xsl:variable>foo</xsl:variable>)
26 ;;; which all end up in the same position of (let ((name OOPS)) ...)
28 ;;; Right now, we require (iii) to be written as (progn ...) while
29 ;;; (ii) is written literally.
31 ;;; Alternatively, we could write (ii) as (:xpath ...) and (iii) literally.
33 ;;; The problem with (i) and (ii) is whether "foo" is an XPath string
34 ;;; (the node test for "foo") or a literal string in a sexp, meaning "'foo'".
35 ;;; Currently we simply don't support (i), which is sad.
37 ((xsl:template :match "xpath" :name "foo" :priority 5 :mode "special")
38 (parameter1 (parameter2 default-value) parameter3)
44 (declare (sort ...) (sort ...)) ;optional sorting declarations
51 (xsl:call-template name
57 :namespace "http://..."
58 :use-attribute-sets ...)
61 (xsl:attribute ("qname" :namespace "http://...")
65 (xsl:unescaped-text "bar")
67 (xsl:processing-instruction name
72 (xsl:copy (:use-attribute-sets ...)
75 (xsl:value-of <xpath>)
76 (xsl:unescaped-value-of <xpath>)
78 (xsl:number :level ... :count ... :bla bla bla)
81 (declare (sort ...) (sort ...)) ;optional sorting declarations
84 ;; this is called <if> in XSLT, but that would be confusing in lisp
88 ;; XSLT doesn't have this, but it seems useful:
92 ;; XSLT doesn't have this, but it seems useful:
97 ;; XSLT doesn't have this, but it seems useful:
101 ;; in XSLT, the children of <choose> are called <when> and <otherwise>,
102 ;; but we should better use a cond-like syntax:
107 (t . otherwise-body))
109 ;; XSLT does this using Dylan-style <xsl:variable>
110 (let ((var1 "/xpath")
113 (var3 (progn (xsl:text "/xpath"))))
115 (let* ((var1 "/xpath")
119 ;; the following is done using xmlns attributes on XSLT elements.
120 ;; We need a similar mechanism to establish namespaces for the XPath
121 ;; strings and other QNames.
122 (xsl:with-namespaces (("prefix1" "uri1")
126 (xsl:copy-of "/xpath")
133 ;; useful only when reading XSL stylesheets in XML syntax, I think.
137 ;; literal element <foo>
138 ;; like xsl:element, but without attribute value template and namespace
139 (xsl:literal-element ("local-name" "http://uri")
140 (xsl:literal-attribute ("name" "ouri")
142 (xsl:literal-attribute ("name")
152 (xuriella::test-instruction
153 `(xsl:element ("bla")
154 (xsl:text "number of children: ")
155 (xsl:value-of "count(test/child)"))
156 "<test><child/><child/></test>")
158 (xuriella::test-instruction
159 `(let (("var" "1+2"))
161 (xsl:value-of "$var")))
162 "<test><child/><child/></test>")