Design Considerations for XSLT Commit Scripts
After you have some experience looking at Junos OS configuration data in XML, creating commit scripts is fairly straightforward. This section provides some recommendations and common patterns for developing commit scripts using XSLT.
XSLT is an interpreted language, making performance an important
consideration. For best performance, minimize node traversals and
testing performed on each node. When possible, use the select attribute on a recursive <xsl:apply-templates> invocation to limit the portion of the document hierarchy being
visited.
For example, the following select attribute limits the nodes to be evaluated by
specifying Ethernet interfaces that have the inet (IPv4) protocol
family enabled:
<xsl:apply-templates select="interfaces/interface[starts-with(name, 'ge-') and unit/family/inet]"/>
The following example contains two <xsl:apply-templates> instructions that limit the scope of the script to the import statements configured at the [edit protocols
ospf] and [edit protocols isis] hierarchy levels:
<xsl:template match="configuration"> <xsl:apply-templates select="protocols/ospf/import"/> <xsl:apply-templates select="protocols/isis/import"/> <!-- ... body of template ... --> </xsl:template>
In an interpreted language, doing anything more than once can affect performance. If the script
needs to reference a node or node set repeatedly, make a variable that holds the node
set, and then make multiple references to the variable. For example, the following
variable declaration creates a variable called mpls that resolves to
the [edit protocols mpls] hierarchy level. Using the variable enables
the script to traverse the /protocols/ hierarchy searching for the
mpls/ node only once.
<xsl:variable name="mpls" select="/protocols/mpls"/> <xsl:choose> <xsl:when test="$mpls/path-mtu/allow-fragmentation"> <!-- ... --> </xsl:when> <xsl:when test="$mpls/hop-limit > 40"> <!-- ... --> </xsl:when> </xsl:choose>
Variables are also important when using <xsl:for-each> instructions
because the current context node examines each node selected by the
<xsl:for-each> instruction. For example, the following script
uses multiple variables to store and refer to values as the
<xsl:for-each> instruction evaluates the E1 interfaces that
are configured on all channelized STM1 (cstm1-) interfaces:
<xsl:param name="limit" select="16"/>
<xsl:template match="configuration">
<xsl:variable name="interfaces" select="interfaces"/>
<xsl:for-each select="$interfaces/interface[starts-with(name, 'cstm1-')]">
<xsl:variable name="triple" select="substring-after(name, 'cstm1-')"/>
<xsl:variable name="e1name" select="concat('e1-', $triple)"/>
<xsl:variable name="count"
select="count($interfaces/interface[starts-with(name, $e1name)])"/>
<xsl:if test="$count > $limit">
<xnm:error>
<edit-path>[edit interfaces]</edit-path>
<statement><xsl:value-of select="name"/></statement>
<message>
<xsl:text>E1 interface limit exceeded on CSTM1 IQ PIC.
</xsl:text>
<xsl:value-of select="$count"/>
<xsl:text> E1 interfaces are configured, but only
</xsl:text>
<xsl:value-of select="$limit"/>
<xsl:text> are allowed.</xsl:text>
</message>
</xnm:error>
</xsl:if>
</xsl:for-each>
</xsl:template>If you channelize a cstm1-0/1/0 interface into 17 E1 interfaces, the script causes the following
error message to appear when you issue the commit command.
[edit] user@host# commit [edit interfaces] 'cstm1-0/1/0' E1 interface limit exceeded on CSTM1 IQ PIC. 17 E1 interfaces are configured, but only 16 are allowed. error: 1 error reported by commit scripts error: commit script failure