Templates

A SLAX script consists of a set of templates. There are two types of templates, match templates and named templates. This section discusses each of these types.

Named Templates

In addition to the template processing, templates can be given explicit names and called directly, allowing a programming style that follows more traditional procedural languages. Named templates are called like function, returning their XML output nodes to the caller, where they can be merged into the caller’s XML output tree.

The template Statement

Named templates are defined using their name and parameters and invoked using the call statement. The template definition consists of the template keyword, the template name, a set of parameters, and a braces-delineated block of code. Parameter declarations can be either inline, with the parameter name and optionally an equals sign (“=”) and a value expression. Additional parameters can be declared inside the block using the param statement.

The template is invoked using the call statement, which consists of the call keyword followed by a set of parameter bindings. These binding are a comma-separated list of parameter names, optionally followed by an equal sign and a value expression. If the value is not given, the current value of that variable or parameter is passed, giving a simple shorthand for passing parameters if common names are used. Additional template parameters can be supplied inside the block using the with statement.

The call Statement

Named templates accept parameters by name, rather than by position. This means the caller needs to indicate the name of the desired parameter when passing a value:

call test($arg1 = 1, $arg4 = 4, $arg2 = 2);

As a convenience, arguments with the same local name as the argument name can be passed directly:

var $message = "test " _ $name _ " is " _ $status;
call emit-message($message)

This is identical to “call emit-message($message = $message)”, but is simpler and the use of common names increased readability.

The call statement can be used as the initial value of a variable or parameter, without using an enclosing set of braces:

var $a = call test($a = 1);

Using the with Statement with call

In addition, template arguments can be passed using the with statement. This statement is placed inside braces after the call statement, and gives the parameter name and the value:

call test {
    with $arg1 = 1;
    with $arg4 = 4;
    with $arg2 = 2;
}

Variables Always Use Dollar Signs

Note that in SLAX parameter names are always prefixed with the dollar sign (“$”). This is not true for XSLT, where the dollar sign is not used when defining variables.

The with statement is described in more detail below (The with Statement).

Using Elements As Argument Values

Beginning with SLAX-1.2, elements may be used directly as argument values for templates. Arguments can be either a single element or a block of SLAX code, placed inside braces:

call my-template($a = <elt>, $b = <max> 15);
call test($params = {
    <min> 5;
    <max> 15;
    if ($step) {
        <step> $step;
    }
}
call write($content = <content> {
    <document> "total.txt";
    <size> $file/size;
    if (node[@type == "full"]) {
        <full>;
    }
});

Combination Templates

While rarely used, XSLT allows named template to be used as match templates. This is done using the match statement after the template statement. For more information on match statements, see The match Statement.

SYNTAX::
    'template' template-name 'match' xpath-expression '{'
        template-contents
    '}'

template test match paragraph ($message) {
    <message> $message;
}

match / {
    call test($message = "called as named template");
    apply-templates {
        with $message = "called as match template";
    }
}

Example with XSLT Translation

This section includes a short example, along with the XSLT into which the script translates.

match configuration {
    var $name-servers = name-servers/name;
    call my:thing();
    call my:thing($name-servers, $size = count($name-servers));
    call my:thing() {
        with $name-servers;
        with $size = count($name-servers);
    }
}

template my:thing($name-servers, $size = 0) {
    <output> "template called with size " _ $size;
}

The XSLT equivalent:

<xsl:template match="configuration">
  <xsl:variable name="name-servers" select="name-servers/name"/>
  <xsl:call-template name="my:thing"/>
  <xsl:call-template name="my:thing">
    <xsl:with-param name="name-servers" select="$name-servers"/>
    <xsl:with-param name="size" select="count($name-servers)"/>
  </xsl:call-template>
  <xsl:call-template name="my:thing">
    <xsl:with-param name="name-servers" select="$name-servers"/>
    <xsl:with-param name="size" select="count($name-servers)"/>
  </xsl:call-template>
</xsl:template>

<xsl:template name="my:thing">
  <xsl:param name="name-servers"/>
  <xsl:param name="size" select="0"/>
  <output>
    <xsl:value-of
         select="concat('template called with size ', $size)"/>
  </output>
</xsl:template>

Match Templates

The processing model for SLAX is identical to that of XSLT. A set of XML input nodes are processed to generate a set of XML output nodes. This processing begins at the top of the XML input document and proceeds recursively through the entire document, using rules defined in the SLAX script, rules imported from other scripts, and a set of default rules defined by the XSLT specification.

Each rule defines the matching criteria that controls when the rule is applied, followed by a template for the creation of the XML output nodes. The processing engine inspects each node, finds the appropriate rule that matches that node, executes the template associated with the rules, builds the XML output nodes, and merges those nodes with the XML output nodes from other rules to build the XML output nodes.

The match Statement

The match statement defines a match template, with its matching criteria and its template. The keyword match is followed by an XPath expression that selects the nodes on which this template should be executed. This is followed by a set of curly braces containing the template.

SYNTAX::
    'match' xpath-expression '{'
        template-contents
    '}'

The template consists of SLAX code, whose statements are defined later in this document.

match configuration {
    <error> {
        <message> "System is named " _ system/host-name;
    }
}

The apply-templates Statement

The apply-templates statement instructs the processing engine to apply the set of templates given in the script to a set of nodes. The statement takes as its argument an XPath expression that selects a set of nodes to use. If no expression is given, the current node is used.

The set of XML input nodes is processed according to the set of templates, and the XML output nodes are given to the context in which the apply-templates statement was issued.

Match templates are applied using the apply-templates statement.

match configuration {
    apply-template system/host-name;
}

match host-name {
    <hello> .;
}

XSLT equivalent

The following is the XSLT equivalent of the above example:

<xsl:template match="configuration">
  <xsl:apply-templates select="system/host-name"/>
</xsl:template>

<xsl:template match="host-name">
  <hello>
    <xsl:value-of select="."/>
  </hello>
</xsl:template>

The apply-templates statement can also contain two substatements. The The mode Statement statement will limit applied templates to those which contain a matching mode statement:

main <top> {
    apply-templates;
    apply-templates {
        mode "index";
    }
}

match catalog {
    mode "index";
    /* do index-y stuff */
}

The The with Statement statement allows parameters to be passed to match templates:

apply-templates target {
    with $replace = "some value";
}

Match templates need a param statement to accept parameters.

The apply-imports Statement

The apply-imports statement mimics the <xsl:apply-imports> element, allowing the script to invoke any imported templates.

apply-imports;

XSLT equivalent

The following is the XSLT equivalent of the above example:

<xsl:apply-imports/>

The mode Statement

The mode statement allows the apply-template to choice a distinct set of rules to use during processing. The argument to the mode statement is a text string that identifies the mode for both the template and the template processing. Templates processing will only select templates that match the current mode value. If no mode statement is given with an apply-templates invocation, then the current mode remains in effect.

This statement can appear inside a match statement, limited that template to the given mode, and inside an apply-templates statement, directing that only that templates matching that mode should be used. The mode is not sticky, so additional apply-templates statements should specify the proper mode.

In this example, template processing is invoked twice, first for mode “one” and then for mode “two”.

match * {
    mode "one";
    <one> .;
}

match * {
    mode "two";
    <two> string-length(.);
}

match / {
    apply-templates version {
        mode "one";
    }
    apply-templates version {
        mode "two";
    }
}

XSLT Equivalent

https://www.w3.org/TR/1999/REC-xslt-19991116#modes

The the mode statement mimics the “mode” attribute of the <xsl:template> element. The following is the XSLT equivalent of the above example:

<xsl:template match="*" mode="one">
  <one>
    <xsl:value-of select="."/>
  </one>
</xsl:template>

<xsl:template match="*" mode="two">
  <two>
    <xsl:value-of select="string-length(.)"/>
  </two>
</xsl:template>

<xsl:template match="/">
  <xsl:apply-template select="version" mode="one"/>
  <xsl:apply-template select="version" mode="two"/>
</xsl:template>

The priority Statement

The priority statement sets the priority of the template, which is used as part of the conflict resolution when more that one template matches a source node. The highest priority rule is chosen. The argument to the priority statement is a real number (positive or negative). The priority statement appears inside a match statement.

In this example, the template is given a high priority:

match * {
    priority 10;
    <output> .;
}

XSLT Equivalent

https://www.w3.org/TR/1999/REC-xslt-19991116#conflict

The priority statement mimics the priority attribute of the <xsl:template> element. The following is the XSLT equivalent of the above example:

<xsl:template match="*" priority="10">
  <output>
    <xsl:value-of select="."/>
  </output>
</xsl:template>

The param Statement

Template can accept parameters from their callers, and scripts can accept parameters from the calling environment (typically the command line). The param statement declares a parameter, along with an optional default value.

SYNTAX::
    'param' parameter-name ';'
    'param' parameter-name '=' optional-value ';'
    'param' parameter-name '=' '{' value-block '}'

EXAMPLE::
    param $address = "10.1.2.3";
    param $count = 25;

    templace count {
        /*
         * This defines a local parameter $count and sets
         * its value to that of the global parameter $count.
         */
        param $count = $count;
    }

Like variables, parameters are immutable. Once created, their value cannot be changed. See Variables for a discussion on dealing with immutable values.

Template parameters can also be defined in a C style following the template name:

template area ($width = 10, $length = 10, $scale = 1) {
    <area> $width * $length * $scale;
}

The with Statement

The with statement supplies a value for a given parameter.

call area {
    with $length = 2;
    with $width = 100;
    with $max;
}

Parameter values may also be passed using a C/perl style, but since arguments in SLAX (and XSLT) are passed by name, the parameter names are also given:

call area($width = 100, $length = 2, $max);

If a parameter is not supplied with a value, the current value of that parameter variable (in the current context) is used, meaning that:

with $max;

is equivalent to:

with $max = $max;

Parameters may be passed to match templates using the with statement. The with statement consists of the keyword with and the name of the parameter, optionally followed by an equals sign (“=”) and a value expression. If no value is given, the current value of that variable or parameter (in the current scope) is passed, giving a simple shorthand for passing parameters if common names are used.

match configuration {
    var $domain = domain-name;
    apply-template system/host-name {
        with $message = "Invalid host-name";
        with $domain;
    }
}

match host-name {
    param $message = "Error";
    param $domain;
    <hello> $message _ ":: " _ . _ " (" _ $domain _ ")";
}

XSLT equivalent

The following is the XSLT equivalent of the above example:

<xsl:template match="configuration">
  <xsl:apply-templates select="system/host-name">
    <xsl:with-param name="message" select="'Invalid host-name'"/>
    <xsl:with-param name="domain" select="$domain"/>
  </xsl:apply-templates>
</xsl:template>

<xsl:template match="host-name">
  <xsl:param name="message" select="'Error'"/>
  <xsl:param name="domain"/>
  <hello>
    <xsl:value-of select="concat($message, ':: ', .,
                                ' (', $domain, ')')"/>
  </hello>
</xsl:template>

The main Template

The XSLT programming model used with SLAX calls for a traversal of the input data hierarchy. Since the first step is typically the match of the top of the hierarchy and the creation of the top-level tag of the output hierarchy. The main statement allows both of these objectives. Two forms of the statement are supported, with and without the output tag. Without an output element, the main template is equivalent to “match /”. The token main is followed by a block of statements within a set of braces:

main {
    <top> {
        <answer> 42;
    }
}

The main template can also be used with a top-level output element following the main token. The element can include attributes.

main <top> {
    <answer> 42;
}

Both of the preceding examples are equivalent to the following XSLT:

<xsl:template match="/">
    <top>
        <answer>42</answer>
    </top>
</xsl:template>