[j-nsp] understaning the copy-node in SLAX
Martin T
m4rtntns at gmail.com
Mon Feb 5 07:46:42 EST 2018
On Fri, Feb 2, 2018 at 10:05 PM, Phil Shafer <phil at juniper.net> wrote:
> Martin T writes:
>>When I run this with traceoptions enabled, then I can see that "<abc
>>a="12" b="34" c="56"/>" is present in the output document. I guess
>>that this inner for-each loop, based on my example, expands to this:
>>
>>copy-node {
>> attribute "a" {
>> expr 12;
>> }
>> attribute "b" {
>> expr 34;
>> }
>> attribute "c" {
>> expr 56;
>> }
>>}
>>
>>Now "copy-node" does its shallow copy and copies "abc" element node
>>and specified three attribute nodes to result tree. Am I correct?
>
> copy-node create a node with the target (default .) name which you
> can then populate with contents:
>
> https://www.w3.org/TR/1999/REC-xslt-19991116#copying
>
> The xsl:copy element provides an easy way of copying the current
> node. Instantiating the xsl:copy element creates a copy of the
> current node. The namespace nodes of the current node are
> automatically copied as well, but the attributes and children
> of the node are not automatically copied. The content of the
> xsl:copy element is a template for the attributes and children
> of the created node; the content is instantiated only for nodes
> of types that can have attributes or children (i.e. root nodes
> and element nodes).
>
> It's rather like:
>
> element name() {
> ...
> }
>
>>In
>>addition, why does copy-node run only once despite the fact that it is
>>in the for-each loop? Is it because copy-node discards all the child
>>elements of its current node and thus there are no more element
>>nodes(<klm>, <name>, <name> based on my example) to loop through?
>
> It's simpler than that; it's copying the current node, so there's
> only one of them. The nested "for-each" hits all the current node's
> attributes, so you end up with:
>
> % cat /tmp/foo.slax
> version 1.2;
>
> var $results := {
> <abc a="12" b="34" c="56"> {
> <klm k="78"> {
> <name n="9"> "foo";
> }
> }
> }
>
> main <top> {
> for-each ($results/abc) {
> copy-node {
> for-each (@*) {
> attribute name(.) {
> expr .;
> }
> }
> }
> }
> }
> % slaxproc -E -g /tmp/foo.slax
> <?xml version="1.0"?>
> <top>
> <abc a="12" b="34" c="56"/>
> </top>
> Bock %
>
> Thanks,
> Phil
Thanks! And this technique is useful in case cli process expects an
element node(for example "interface-information") to have additional
attribute nodes(for example "junos:style="terse"")? Does it provide
any advantages over statically specifying the attribute node? For
example, here I rewrote two named templates and a match template of an
op script example from "Automating Junos Administration" book:
template handle-logical-intf($family) {
<logical-interface> {
for-each (*[name() != "address-family"]) {
copy-of .;
}
for-each (address-family[address-family-name=$family]) {
copy-of .;
}
}
}
template handle-physical-intf($family) {
<physical-interface> {
for-each (*[name() != "logical-interface"]) {
copy-of .;
}
for-each (logical-interface[address-family[
address-family-name=$family]]) {
call handle-logical-intf($family=$family);
}
}
}
match / {
<op-script-results> {
var $con = jcs:open();
var $rpc-query = {
<get-interface-information> {
<terse>;
}
}
var $results = jcs:execute($con, $rpc-query);
expr jcs:close($con);
if ($family) {
<interface-information junos:style="terse"> {
for-each
($results/physical-interface[logical-interface/
address-family[address-family-name=$family]]) {
call
handle-physical-intf($family=$family);
}
}
}
else {
copy-of $results;
}
}
}
It behaves exactly the same as the one using the copy-node statements.
thanks,
Martin
More information about the juniper-nsp
mailing list