1
2 XSS - XML based SableCC Stylesheets
3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 XSS stylesheets allow you to easily generate custom output from
5 SableCC's. XSS was originally built on XML and XSL transforms but
6 now works as a standalone system.
7
8 The XSS produces output based on input data tree. It can be mapped
9 into XML using the xml target.
10
11 Therefore it is imperative to understand its structure. Generate one (XML).
12 Inspect it in Mozilla or IE. Close and open elements. See what's
13 inside. Know what the attributes represent. This is the basic structure:
14
15 parser
16 tokens
17 token*
18 prods
19 prod*
20 alt*
21 elem*
22 lexer_data
23 state*
24 accept_table
25 state*
26 i*
27 goto_table
28 state*
29 goto*
30 parser_data
31 action_table
32 row*
33 action*
34 goto_table
35 row*
36 action*
37 errors
38 i*
39 error_messages
40 msg*
41 rules
42 rule*
43 action*
44 arg*
45
46 Out of all that the most interesting part is only the tiny top:
47
48 parser
49 tokens
50 token*
51 prods
52 prod*
53 alt*
54 elem*
55
56 This contains the tokens and the structure of the abstract syntax tree.
57
58 The stylesheet system implements a subset of the W3's XPath language
59 to perform simple queries etc.
60
61 The thing to understand is that the xpath expressions always work in the
62 context of the element you're at. By default that element would be
63 /parser. But if you do a foreach then inside the foreach content block the
64 context changes to the element you're at.
65
66 XSS is a mixed set of text and command blocks. In this document the
67 command names are always in capitals. To go into and then out of
68 command block [- and -] or for a whole line '$ ' at start are used.
69 Additionally inside the text you can specify inline replaceble elements
70 that are taken from current context.
71
72 A little example:
73
74 @package
75
76 $ FOREACH {//token}
77 @name
78 $ END FOREACH
79
80 This would output the package name (attribute named 'package' on /parser),
81 then we'd loop over all the tokens and print their names. The command names
82 in practice are case insensitive and you don't have to use the command
83 name at END.
84
85
86 * Inline outputing: @attrib, $var and ${<xpath-expr>}
87 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
88 Usage:
89 ..content..
90 @attrib
91 @{attrib}
92 $varname
93 ${<xpath-expr>}
94 ..content..
95
96 These allow us to insert values from the current context element into
97 the output.
98
99 Examples:
100
101 @package
102
103 Mixed@{package}string.
104
105 In case we are at top context (the /parser) outputs the package attribute
106 of parser.
107
108 [-SET nick='Joe'-]
109 $nick
110
111 Outputs the variable/parameter named 'nick'. You can SET or PARAM
112 variables and also they're implicitly used at TEMPLATE/CALL.
113
114 The shortcut $ and @ forms can be followed by a series of letters or
115 numbers or underscores but it must start with a letter.
116
117 ${../@ename}
118
119 This is the long xpath expression form. Insert the attribute 'ename'
120 from parent element.
121
122 Obviously to accomplish all this $ and @ are special symbols. To get them
123 themselves into the output you just have to double them.
124
125 @@$$
126
127 This should output '@$'. Inside the ${<xpath-expr>} the curly braces
128 are also special and have to be doubled to be used. One more special
129 escaped combination is '[--' - it is read as text and translated
130 to '[-'. With single dash ([-) it would mean the start of a command.
131
132 The shortcut @attrib and $var syntax can also be used where expression
133 is expected inside command block (except foreach).
134
135
136 * Commands
137 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
138 Commands represent the control structure of a template. Commands
139 allow conditional displaying, looping over elements and even
140 specifying the output file name.
141
142 XSS supports basically similar set of commands that are available
143 in XSL. There are some differences tho:
144
145 Notably we have IF-ELSE while there is no else construct in the XSL.
146
147 Commands have to be placed into tags [- -].
148
149 There is now also a new shortcut syntax for commands that take
150 up only one line - if the first two characters of a line
151 are '$ ' (dollar space) then the rest of line is implied as
152 command and wrapped into [- .. -]:
153
154 This is from beginning of line
155 This is from beginning of line
156 This is from beginning of line
157 $ foreach {elem}
158 Same as writing:
159 [-foreach {elem}-]
160
161
162 * XPath - supported functions
163 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
164 These are the currently implemented and supported functions:
165
166 position()
167 count(node-selection)
168 translate(string, from, to)
169 concat(str1,..)
170 not(expr)
171 string(expr)
172 contains(string,search)
173
174 Also several non-standard functions are available:
175
176 reverse(node-selection)
177 sablecc:string2escaped_unicode(str)
178 sablecc:toxml(node-selection,ident-amount)
179 sablecc:toggle(domain-string,token-string)
180
181 Separators:
182 /
183 //
184
185 In xpath expressions these special nodes are supported:
186 .
187 ..
188
189 No axis etc. are supported.
190
191 There is no director support for booleans - anything not null is considered
192 true. The same goes for numbers - everything is converted to and from
193 strings where necessary.
194
195 Supported Xpath operators:
196 +
197 -
198 =
199 !=
200
201
202 * FOREACH
203 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
204 Usage:
205
206 [-FOREACH [name IN] <xpath-expr>-]
207 ..content..
208 [-END FOREACH-]
209
210 Foreach allows you to loop over a set of elements and output the
211 content for every one of them. The selection is provided by
212 a xpath expression.
213
214 If name is specified then a variable with that name is set
215 to given element. That could also be accomplished with [-SET-].
216
217 As you foreach through elements the context in which the content
218 is evaluated changes to the element you're looping at.
219
220 Examples:
221
222 [-FOREACH {//alt}-]
223
224 Foreach over all elements in the document that are named 'alt'.
225
226 [-FOREACH {elem}-]
227
228 Foreach over all XML elements named elem that are directly under
229 current context.
230
231 [-FOREACH {//token[position()=1]}-]
232
233 Loop over the first token (only one element).
234
235 [-FOREACH {//token[@value]}-]
236
237 Loop over all tokens that have a value attribute (eg. fixed
238 tokens).
239
240 [-FOREACH {elem[@is_list='true']}-]
241
242 Loop over all elem-s that are under given context and
243 additinally must meet the condition that they are lists.
244
245 The need for 'name IN' construct is very rare. It comes when
246 you need to cross-reference from one context into another.
247 See java/lexer.xss where it's used in that form.
248
249
250 * IF and IF .. ELSE
251 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
252 Usage:
253
254 [-IF <expr>-]
255 ..content..
256 [-END IF]
257
258 [-IF <expr>-]
259 ..content..
260 [-ELSE-]
261 ..content..
262 [-END IF-]
263
264 IF allows you to ouput content depending on some test. The test
265 would usually be an xpath expression.
266
267 Examples:
268
269 [-IF {not(@is_list)}-]
270 System.out.println ("NOT A LIST!");
271 [-ELSE-]
272 System.out.println ("IS A LIST!");
273 [-END IF-]
274
275 Test whether the element in current context does not have an
276 attribute named is_list.
277
278
279 * CHOOSE, WHEN and OTHERWISE
280 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
281 Usage:
282
283 [-CHOOSE-]
284 [-WHEN <expr>-]
285 ..content..
286 [-END WHEN-]
287 ..
288 [-OTHERWISE-]
289 ..content..
290 [-END OTHERWISE-]
291 [-END CHOOSE-]
292
293 CHOOSE tests the WHEN conditions and when one is met its content
294 is processed and outputed. After that nothing more is
295 searched/outputed. But when no WHEN was found and OTHERWISE
296 is present then its content is outputed.
297
298 Example:
299
300 [-CHOOSE-]
301 [-WHEN {@age>64}-]
302 You are old and wise!
303 [-END WHEN]
304 [-WHEN {@age>32}-]
305 You should get married if you're not yet!
306 [-END WHEN]
307 [-WHEN {@age>18}-]
308 You can get drunk!
309 [-END WHEN-]
310 [-OTHERWISE-]
311 You need to grow a bit!
312 [-END OTHERWISE-]
313 [-END CHOOSE-]
314
315 As you should guess this tests the current context element's attribute
316 'age' and prints output depending on its value.
317
318
319 * TEMPLATE and CALL
320 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
321 Usage:
322
323 [-TEMPLATE name([arg [= <expr>] [, ..]])-]
324 ..template content..
325 [-END TEMPLATE-]
326
327 [-CALL name([arg = <expr> [, ..]])-]
328
329 There are people who are obsessed with reuse. These two commands
330 provide that functionality. They allow you to write a template
331 that can be later called in any place in your stylesheet.
332
333 The arguments will be added as variables ($arg) and can be
334 referenced inside the TEMPLATE.
335
336 Example:
337
338 [-TEMPLATE myname(name, loves='Jesus')-]
339 Hello, my name is $name and I love $loves.
340 [-END TEMPLATE-]
341
342 [-CALL myname(name='John', loves='Jane')-]
343 [-CALL myname(name='Bob', loves='Jane')-]
344 [-CALL myname(name='Jane')-]
345
346 Output:
347
348 Hello, my name is John and I love Jane.
349 Hello, my name is Bob and I love Jane.
350 Hello, my name is Jane and I love Jesus.
351
352 As you can see you can provide default values for arguments.
353 And you can omit any argument. Also argument order is
354 unspecified.
355
356 The context inside the template changes to where it was called from.
357
358
359 * INCLUDE
360 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
361 Usage:
362
363 [-INCLUDE '<path>'-]
364
365 You can split your stylesheets into multiple chunks and then assemble
366 them using INCLUDE. The path is taken to be in the directory context
367 of the calling stylesheet.
368
369 Example:
370
371 [-INCLUDE 'library1.xss'-]
372 [-INCLUDE 'library2.xss'-]
373 [-INCLUDE 'library3.xss'-]
374
375
376 * OUTPUT
377 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
378 Usage:
379
380 [-OUTPUT <path-expr>-]
381 ..content..
382 [-END OUTPUT-]
383
384 Output allows you to redirect all the content into a file specified by
385 <path-expr>. The path-expr can be a xpath expression.
386
387 Examples:
388
389 [-OUTPUT 'out.txt'-]
390 This output goes to out.txt!
391 [-END OUTPUT-]
392
393 Produces a file named out.txt.
394
395 [-FOREACH {//token}-]
396 [-OUTPUT {concat(@ename,'.java')}-]
397 public class @ename {
398 ..
399 }
400 [-END OUTPUT-]
401 [-END FOREACH-]
402
403 Loops over all tokens and creates a file for each of them.
404
405 * SEP
406 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
407 Usage:
408 [-SEP ','-]
409
410 This must be used inside a FOREACH loop. It outputs its argument
411 unless the FOREACH is processing its last element. So it's an
412 easy way to provide separators between elements.
413
414 Example:
415
416 [-FOREACH {//token}-]
417 @ename[-sep ', '-]
418 [-END-]
419
420
421 * SET and PARAM
422 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
423 Usage:
424 [-SET varname = <expr> [, ..] -]
425
426 [-PARAM parname [= <expr>] [, ..] -]
427
428 XSS/XSL stylesheets can take arguments. The arguments have to be described
429 using the PARAM command. For example the output directory were all files
430 should be generated is such a PARAM.
431
432 SET is used for variables inside loops and otherwise. SET is not an
433 assignment but a context/scope dependant rebinding. So you can't really do
434 imperative programming using it.
435
436 SET is implicitly used at named FOREACH and also TEMPLATE/CALL.
437
438 Wherever you define PARAM-s they are removed and placed into global
439 scope outside any output generation. So PARAM-s can't be redefined.
440
441 * PRINT
442 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
443 Usage:
444 [-PRINT <expr>-]
445
446 Used to simply print out an expression to output stream. Does not
447 generate any white space (line breaks, etc).
448
449
450 Example:
451
452 [-PRINT 'Hello, world!'-]
453
454
455 * Comments
456 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
457 Usage:
458 [-
459 // This is a comment.
460 // These won't be in the output
461 COMMAND
462 -]
463
464 [-!
465 This is also a comment, can contain [- and -]
466 !-]
467
468 $ // Comment
469
470
471
Generated with
vim2html
Copyright © 2003 by Chip Cuccio
<http://norlug.org/~chipster/?finger>