SLAX 模板概述
SLAX 脚本由一组或多个规则组成,称为 模板。每个模板都是一个代码段,包含在匹配指定节点时要应用的规则。
Junos OS 版本 14.2 和更高版本中支持的 SLAX 语言版本 1.2 支持 SLAX 元素作为模板和功能的参数。
以下部分中介绍了两种类型的模板,包括命名和未命名(或匹配)。
未命名(匹配)模板
未命名模板(也称为 match 模板)包含带 match
XPath 表达式的语句,用于指定应调用模板的节点标准。在以下提交脚本示例中,该模板与配置层次结构中的顶级元素匹配:
match configuration { /* ...body of the template goes here */ }
默认情况下,处理器会反复遍历整个文档层次结构,检查每个节点并寻找与当前节点匹配的模板。找到匹配模板时,会评估该模板的内容。
该 apply-templates
语句可用于未命名模板内,以限制和控制节点的默认层次结构遍历。此语句接受可选 XPath 表达式,此表达式等同于 select
元素 <xsl:apply-templates>
中的属性。如果包含可选 XPath 表达式,则仅遍历与 XPath 表达式匹配的节点。否则, 上下文节点 的所有儿童都会遍历。如果包含 XPath 表达式但与任何节点不匹配,则不会遍历任何节点,也不会发生任何情况。
在以下示例中,模板规则匹配 <route>
XML 层次结构中的元素。所有包含属性的changed
节点均会进行处理。包含属性changed
的所有route
元素都将替换为一个new
元素。
match route { <new> { apply-templates *[@changed]; } }
XSLT 等效物:
<xsl:template match="route"> <new> <xsl:apply-templates select="*[@changed]"/> </new> </xsl:template>
使用未命名的模板允许脚本忽略 XML 层次结构中标记的位置。例如,如果您想将所有 <author>
标记转换为 <div class="author">
标记,则使用模板可创建一个规则来转换所有 <author>
标记,而不管它们在输入 XML 文档中的位置如何。
命名模板
命名模板像传统编程语言中的功能一样运行。当脚本的复杂性增加或代码分段出现在多个位置时,您可以对代码进行模块化并创建名为模板的模板。与功能类似,命名模板支持参数,并且仅在明确调用时运行。
在 SLAX 中,命名模板定义包含 template
关键字、模板名称、一组参数和一个括号划定的代码块。参数声明可以内联,由参数名称组成,并可选为默认值。或者,您也可以使用 param
语句在模板块内声明参数。如果未定义默认值,参数将默认为空字符串。
以下示例创建名为 的模板 my-template
并定义三个参数,其中一个参数默认用于字符串 false
,其中一个用于默认指定 name
为当前上下文节点子的元素节点的内容。如果脚本调用模板且未在参数中传递,则使用默认值。
template my-template ($a, $b = "false", $c = name) { /* ... body of the template ... */ }
另一种方法是使用 param
语句在模板内声明参数。以下代码与上一个示例相同:
template my-template { param $a; param $b = "false"; param $c = name; /* ... body of the template ... */ }
在 SLAX 中,您使用call
由关键字和模板名称组成的call
语句调用命名模板,然后使用一组参数绑定。这些绑定是参数名称的逗号分隔列表,用于从调用环境传入模板。参数分配按名称进行,而不是按列表中的位置进行。或者,您也可以使用 with
语句在块内call
声明参数。传入模板的参数必须与实际模板中定义的参数匹配;否则参数会被忽略。或者,您可以为每个参数设置一个值。如果不为调用环境中的参数定义值,则脚本将在参数的当前值(如果之前已初始化)中传递,或者在参数从未被宣布时生成错误。有关传递参数的详细信息,请参阅 SLAX 参数概述。
在以下示例中,使用该模板 my-template
调用参数 c
,其中包含名为 other-name
当前上下文节点子的元素节点的内容:
call my-template { with $c = other-name; }
在以下示例中 name-servers-template
,声明两个参数: name-servers
和 size
。该 size
参数的默认值为零。匹配模板,声明和初始化 name-servers
,调用 name-servers-template
三次。
第一次调用模板时不包含任何参数。因此 name-servers
,将默认为空字符串,默 size
认为模板中定义的零值。第二个调用包括 name-servers
和 size
参数,但仅提供该 size
参数的值。因此 name-servers
,其在脚本中的初始化定义了值, size
等于配置层次结构中的元素数量 name-servers
。最后一个调用与第二个调用相同,但它使用 with
语句语法提供参数。
match configuration { param $name-servers = name-servers/name; call name-servers-template(); call name-servers-template($name-servers, $size = count($name-servers)); call name-servers-template() { with $name-servers; with $size = count($name-servers); } } template name-servers-template($name-servers, $size = 0) { <output> "template called with size " _ $size; }
XSLT 等效体是:
<xsl:template match="configuration"> <xsl:variable name="name-servers" select="name-servers/name"/> <xsl:call-template name="name-servers-template"/> <xsl:call-template name="name-servers-template"> <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="name-servers-template"> <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="name-servers-template"> <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>