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>