The libslax Distribution¶
SLAX is available as an open-source project with the “New BSD” license. Current releases, source code, documentation, and support materials can be downloaded from:
The libslax Library¶
The core of the distribution is the libslax library, which incorporates a SLAX parser to read SLAX files, a SLAX writer to write SLAX files, a debugger, a profiler, and a commandline tool.
The reader turns a SLAX source file into an XSLT tree (xmlDocPtr) using the xsltSetLoaderFunc() hook. The writer turns an XSLT tree (xmlDocPtr) into a file containing SLAX statements.
To support SLAX in your application, link with libslax and call the libslax initializer function:
#include <libslax/slax.h>
slaxEnable(1);
slaxproc: The SLAX Processor¶
The SLAX software distribution contains a library (libslax) and a command line tool (slaxproc). The command line tool can be used to convert between XSLT and SLAX syntax, as well as run stylesheets and check syntax.
Usage: slaxproc [mode] [options] [script] [files]
Modes:
--check OR -c: check syntax and content for a SLAX script
--format OR -F: format (pretty print) a SLAX script
--json-to-xml: Turn JSON data into XML
--run OR -r: run a SLAX script (the default mode)
--show-select: show XPath selection from the input document
--show-variable: show contents of a global variable
--slax-to-xslt OR -x: turn SLAX into XSLT
--xml-to-json: turn XML into JSON
--xpath <xpath> OR -X <xpath>: select XPath data from input
--xslt-to-slax OR -s: turn XSLT into SLAX
Options:
--debug OR -d: enable the SLAX/XSLT debugger
--empty OR -E: give an empty document for input
--exslt OR -e: enable the EXSLT library
--expression <expr>: convert an expression
--help OR -h: display this help message
--html OR -H: Parse input data as HTML
--ignore-arguments: Do not process any further arguments
--include <dir> OR -I <dir>: search dir for includes/imports
--indent OR -g: indent output ala output-method/indent
--indent-width <num>: Number of spaces to indent (for --format)
--input <file> OR -i <file>: take input from the given file
--json-tagging: tag json-style input with the 'json' attribute
--keep-text: mini-templates should not discard text
--lib <dir> OR -L <dir>: search dir for extension libraries
--log <file>: use given log file
--mini-template <code> OR -m <code>: wrap template code in script
--name <file> OR -n <file>: read the script from the given file
--no-randomize: do not initialize the random number generator
--no-tty: Do not use tty for sdb and other input needs
--no-json-types: do not insert 'type' attribute for --json-to-xml
--output <file> OR -o <file>: make output into the given file
--param <name> <value> OR -a <name> <value>: pass parameters
--partial OR -p: allow partial SLAX input to --slax-to-xslt
--slax-output OR -S: emit SLAX-style XML output
--trace <file> OR -t <file>: write trace data to a file
--verbose OR -v: enable debugging output (slaxLog())
--version OR -V: show version information (and exit)
--write-version <version> OR -w <version>: write in version
Project libslax home page: https://github.com/Juniper/libslax
To use slaxproc to convert a SLAX file to XSLT:
$ slaxproc -x mine.slax new.xsl
To convert an XSLT file to SLAX:
$ slaxproc -s existing.xsl new.slax
To run a script:
$ slaxproc mine.slax infile.xml outfile.xml
Use the -g
option to produce good-looking output by enabling
indenting (aka “pretty-printing”) of output. In this example,
since the output filename is not given, the output is written to
the standard output stream (stdout):
$ slaxproc -g mine.slax infile.xml
Use the -p
flag to perform conversion of SLAX and XML
formats for partial data files. This can be used as a filter inside
an editor to convert a region from one format to the other:
$ cat in.xml | slaxproc -s -p > out.slax
Use the -w
option to restrict the output of slaxproc to 1.0
features.
Argument Handling¶
slaxproc
accepts the script name, input name, and output name in two ways.
You can say:
slaxproc script.slax input.xml output.xml
using positional arguments. This way allows slaxproc to be plug compatible with xsltproc.
The other way is to give explicit option values using -n
,
-i
, and -o
. The above command line can be given
as:
slaxproc -i input.xml -n script.slax -o output.xml
These options can be in any order and can be intermixed with other arguments. If none of the values are given, they can still be parsed positionally. In this example, the script name is positional but the input and output file names are positional:
slaxproc -i input.xml -o output.xml -g -v script.slax
“#!” Support¶
SLAX supports the “#!” unix scripting mechanism, allowing the first line of a script to begin with the characters “#” and “!” followed by a path to the executable that runs the script and a set of command line arguments. For SLAX scripts, this might be something like:
#!/usr/bin/slaxproc -n
or:
#!/opt/local/bin/slaxproc -n
or:
#!/usr/bin/env slaxproc -n
The operating system will add the name of the scripts and any command
line arguments to the command line that follows the “#!”. Adding the
-n
option (as shown above) allows additional arguments to be
passed in on the command line. Flexible argument parsing allows
aliases and #! arguments to tailor the slaxproc invocation to match
specific needs. For example if a script begins with:
#!/usr/bin/slaxproc -E -n
then additional slaxproc arguments can be given:
$ that-script -g output.xml
and the resulting command should be:
/usr/bin/slaxproc -E -n /path/to/that-script -g output.xml
The -E
option tells slaxproc to use an empty input document,
removing the need for the -i
option or a positional argument.
If the input or output arguments have the value “-” (or is not given), the standard input or standard output file will be used. This allows slaxproc to be used as a traditional unix filter.
Command Line Options¶
Command line options to slaxproc can be divided into two types. Mode options control the operation of slaxproc, and are mutually exclusive. Behavioral options tailor the behavior of slaxproc in minor ways.
Modes Options¶
-
--check
¶
-
-c
¶
Perform syntax and content check for a SLAX script, reporting any errors detected. This mode is useful for off-box syntax checks for scripts before installing or uploading them.
% slaxproc --check ~/trash/test.slax script check succeeds
-
--format
¶
-
-F
¶
Format (aka “pretty print”) a SLAX script, correcting indentation and spacing to the style preferred by the author (that is, me).
% slaxproc --format ugly.slax pretty.slax
-
--json-to-xml
¶
Transform JSON input into XML, using the conventions defined in JSON Elements.
% echo '{"a": "b"}' | slaxproc --json-to-xml <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <json> <a>b</a> </json>
-
--run
¶
-
-r
¶
Run a SLAX script. The script name, input file name, and output file name can be provided via command line options and/or using positional arguments as described in Argument Handling. Input defaults to standard input and output defaults to standard output.
-r
is the default mode for slaxproc.The following command lines are equivalent:
% slaxproc my-script.slax input.xml output.xml % slaxproc -r -n my-script.slax -i input.xml -o output.xml
-
--show-select
<xpath-expression>
¶ Show an XPath selection from the input document. Used to extract selections from a script out for external consumption. This allows the consumer to avoid a SLAX parser, but still have visibility into the contents of the script.
The output is returned inside an XML hierarchy with a root element named “select”. This makes it possible to return attributes:
% slaxproc --show-select 'xsl:template/@match' script.slax <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <select match="@* | * | processing-instruction() | comment()"/>
-
--show-variable
<variable-name>
¶ Show contents of a global variable. Used to extract static variable contents for external consumption. This allows the consumer of the data to avoid a SLAX parser, but still have access to the static contents of global variables, such as the $arguments variable.
The output is returned inside an XML hierarchy with a root element named “select”:
% slaxproc --show-variable '$global' script.slax <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <select> <xsl:variable xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="global"> <thing> <xsl:value-of select="1"/> </thing> <thing> <xsl:value-of select="2"/> </thing> </xsl:variable> </select>
-
--slax-to-xslt
¶
-
-x
¶
Convert a SLAX script into XSLT format. The script name and output file name can be provided via command line options and/or using positional arguments as described in Argument Handling.
% slaxproc --slax-to-xslt my-script.slax your-script.xsl
-
--xml-to-json
¶
Transform XML input into JSON, using the conventions defined in JSON Elements.
% echo '<json><a>b</a></json>' | slaxproc --xml-to-json { "a": "b" }
-
--xpath
<xpath-expression>
¶
-
-X
<xpath-expression>
¶ Select data matching an XPath data from input document. This allows slaxproc to operate as a filter. Note that
--xpath
and--show-select
differ only in the lack of the root element on the latter:% slaxproc --xpath 'xsl:stylesheet/xsl:template/@match' /tmp/foo.xsl <?xml version="1.0"?> <results match="@* | * | processing-instruction() | comment()"/>
-
--xslt-to-slax
¶
-
-s
¶
Convert a XSLT script into SLAX format. The script name and output file name can be provided via command line options and/or using positional arguments as described in Argument Handling.
% slaxproc --xslt-to-slax your.xsl my.slax
Behavioral Options¶
-
--debug
¶
-
-d
¶
Enable the SLAX/XSLT debugger. See The SLAX Debugger (sdb) for complete details on the operation of the debugger.
-
--empty
¶
-
-E
¶
Provide an empty document as the input data set. This is useful for scripts that do not expect or need meaningful input. The input document consists only of a root element (“top”):
% slaxproc -E -m 'main <top> { copy-of /;} ' <?xml version="1.0"?> <top/>
-
--exslt
¶
-
-e
¶
Enables the EXSLT library, which provides a set of standard extension functions. See exslt.org for more information.
This option is deprecated; SLAX now finds all extension functions automatically and no longer needs specific instructions for the EXSLT library.
-
--expression
<expr>
¶ Converts a SLAX expression to an XPATH one, or vice versa, depending on the presence of –slax-to-xslt and –xslt-to-slax.
% slaxproc -x --expression 'f[name == $one _ "-ext" && mtu]' f[name = concat($one, "-ext") and mtu]
-
--help
¶
-
-h
¶
Displays this help message and exits. The help message has received an unknown number of industry awards from various well-meaning organizations.
-
--html
¶
-
-H
¶
Parse input data using the HTML parser, which differs from XML. The rules are more flexible, but are HTML specific.
-
--ignore-arguments
¶
Do not process any further arguments. This can be combined with “#!” to allow “distinct” styles of argument parsing.
-
--include
<dir>
¶
-
-I
<dir>
¶ Add a directory to the list of directories searched for include and import files. The environment variable SLAXPATH can be set to a list of search directories, separated by colons.
-
--indent
¶
-
-g
¶
Indent output to make it good looking, aka “pretty-printing”. This option is identical to the behavior triggered by the ref:
output-method <output-method>
’sindent
statement:output-method { indent "true"; }
-
--indent-width
¶
Change the default indent level from the default value of 4. This only affects
--format
mode.
-
--input
<file>
¶
-
-i
<file>
¶ Use the given file for input.
-
--json-tagging
¶
Tag JSON elements in SLAX script input with the ‘json’ attribute as they are parsed into XML. This allows the
--format
mode to transform them back into JSON format.
-
--keep-text
¶
When building a script from mini-templates, do not add a template to discard normal text. By default XSLT will display unmatched text data, but mini-templates adds a discard action automatically. The
--keep-text
option preserves the original default behavior instead of replacing it with the discard action that is typically more desirable .
-
--lib
<dir>
¶
-
-L
<dir>
¶ Add a directory to the list of directories searched for extension libraries.
-
--log
<file>
¶ Write log data to the given file, rather than the default of the standard error stream.
-
--mini-template
<code> or -m <code>
¶ Allows a simple script to be passed in via the command line using one of more
-m
options. The argument to-m
is typically a template, such as a named or match template, but can be any top-level SLAX statement.% slaxproc -E -m ‘main <top> { expr date:time(); }’ <?xml version=”1.0”?> <top>19:51:11-05:00</top>
-
--name
<file>
¶
-
-n
<file>
¶ Use the given file as the SLAX script.
-
--no-json-types
¶
Do not generate the “type” attribute in the XML generated by
--json-to-xml
. This type is needed to “round-trip” data back into JSON, but is not needed for simple XML output.
-
--no-randomize
¶
Do not initialize the random number generator. This is useful if you want the script to return identical data for a series of invocation, which is typically only used during testing.
-
--no-tty
¶
Do not use a tty for
sdb
and other tty-related input needs.
-
--output
<file>
¶
-
-o
<file>
¶ Write output into the given file.
-
--param
<name> <value>
¶
-
-a
<name> <value>
¶ Pass a parameter to the script using the name/value pair provided. Note that all values are string parameters, so normal quoting rules apply.
-
--partial
¶
-
-p
¶
Allow the input data to contain a partial SLAX script, with more flexible input parsing. This can be used with the
--slax-to-xslt
to perform partial transformations, or with--format
to format sections of SLAX input or to convert XML into SLAX:% echo '<top><a>b</a></top>' | slaxproc -s -p <top> { <a> "b"; }
-
--slax-output
¶
-
-S
¶
Write the output of a script using SLAX-style XML (braces, etc).
-
--trace
<file>
¶
-
-t
<file>
¶ Write trace data to the given file.
-
--verbose
¶
-
-v
¶
Adds very verbose internal debugging output to the trace data output, including calls to the slaxLog() function.
-
--version
¶
-
-V
¶
Show version information and exit.
-
--write-version
<version>
¶
-
-w
<version>
¶ Write in the given version number on the output file for
-x
or-s
output. This can be also be used to limit the conversion to avoid SLAX 1.1 feature (using-w 1.0
).In this example, the
-w 1.0
option causesslaxproc
to write themain
statement introduced in SLAX-1.2 in a 1.0 compatible manor:% slaxproc --format -m 'main <top> { } ' -w 1.0 --keep-text version 1.0; match / { <top>; }
The SLAX Debugger (sdb)¶
The SLAX distribution includes a debugger called sdb
, which can be
accessed via the slaxproc
command using the -d
option. The
debugger resembles gdb
command syntax and operation.
(sdb) help
List of commands:
break [loc] Add a breakpoint at [file:]line or template
callflow [val] Enable call flow tracing
continue [loc] Continue running the script
delete [num] Delete all (or one) breakpoints
finish Finish the current template
help Show this help message
info Showing info about the script being debugged
list [loc] List contents of the current script
next Execute the over instruction, stepping over calls
over Execute the current instruction hierarchy
print <xpath> Print the value of an XPath expression
profile [val] Turn profiler on or off
reload Reload the script contents
run Restart the script
step Execute the next instruction, stepping into calls
where Show the backtrace of template calls
quit Quit debugger
The info
command can display the following information:
(sdb) info help
List of commands:
info breakpoints Display current breakpoints
info insert Display current insertion point
info locals Display local variables
info output Display output document
info profile [brief] Report profiling information
Many of these commands follow their “gdb” counterparts, to the extent possible.
The location for the break
, continue
, and list
commands can be
either a line number of the current file, a filename and a line
number, separated by a colon, or the name of a template.
(sdb) b 14
Breakpoint 1 at file ../tests/core/test-empty-21.slax, line 14
(sdb) b 19
Breakpoint 2 at file ../tests/core/test-empty-21.slax, line 19
(sdb) b three
Breakpoint 3 at file ../tests/core/test-empty-21.slax, line 24
(sdb) info br
List of breakpoints:
#1 template one at ../tests/core/test-empty-21.slax:14
#2 template two at ../tests/core/test-empty-21.slax:19
#3 template three at ../tests/core/test-empty-21.slax:24
(sdb)
Information on the profiler is in the next section (The SLAX Profiler).
The info insert
and info output
commands allow visibility into the
current output document being generated by libxslt. insert
shows
the current insertion point, typically as an XML hierarchy, where the
next element inserted will appear at the end of that hierarchy.
output
displays the current state of the entire output document.
The info locals
command displays the current set of local variables
and their values.
The SLAX Profiler¶
The SLAX debugger includes a profiler which can report information about the activity and performance of a script. The profiler is automatically enabled when the debugger is started, and tracks script execution until the script terminates. At any point, profiling information can be displayed or cleared, and the profiler can be temporarily disabled or enabled.
Use the profile
command to access the profiler:
(sdb) help profile
List of commands:
profile clear Clear profiling information
profile off Disable profiling
profile on Enable profiling
profile report [brief] Report profiling information
(sdb)
The profile report includes the following information:
- Line – line number of the source file
- Hits – number of times this line was executed
- User – the number of microseconds if “user” time spent processing this line
- U/Hit – average number of microseconds per hit
- System – the number of microseconds if “system” time spent processing this line
- S/Hit – average number of microseconds per hit
- Source – Source code line
The brief
option instructs sdb to avoid showing lines that were not
hit, since there is no valid information for them. Without the
brief
option, dashes are displayed.
In the following example, the source code data is heavily truncated (with “….”) to allow the material to fit on this page. sdb would not truncate these lines:
(sdb) run
<?xml version="1.0"?>
<message>Down rev PIC in Fruvenator, Fru-Master 3000</message>
Script exited normally.
(sdb) profile report
Line Hits User U/Hit System S/Hit Source
1 - - - - - version 1.0;
2 - - - - -
3 2 4 2.00 8 4.00 match / {
4 1 25 25.00 13 13.00 var ....
5 - - - - -
6 - - - - - for-each....
7 1 45 45.00 10 10.00 ..
8 1 12 12.00 5 5.00 <message>
9 1 45 45.00 15 15.00 ....
10 - - - - - }
11 - - - - - }
Total 6 131 51 Total
(sdb) pro rep b
Line Hits User U/Hit System S/Hit Source
3 2 4 2.00 8 4.00 match / {
4 1 25 25.00 13 13.00 var ....
7 1 45 45.00 10 10.00 ....
8 1 12 12.00 5 5.00 <message>
9 1 45 45.00 15 15.00 ....
Total 6 131 51 Total
(sdb)
This information not only shows how much time is spent during code execution, but also shows which lines are being executed, which can help debug scripts where the execution does not match expectations.
The profiling is not “Monte Carlo”, or clock based, but is based on trace data generated as each SLAX instruction is executed, giving more precise data.
callflow¶
The callflow
command enables the printing of informational data when
levels of the script are entered and exited. The lines are simple,
but reference the instruction, filename, and line number of the
frame:
callflow: 0: enter <xsl:template> in match / at empty-15.slax:5
callflow: 1: enter <xsl:variable> at empty-15.slax:13
callflow: 1: exit <xsl:variable> at empty-15.slax:13
callflow: 1: enter <xsl:variable> at empty-15.slax:20
callflow: 1: exit <xsl:variable> at empty-15.slax:20
callflow: 0: exit <xsl:template> in match / at empty-15.slax:5