01-10-2019 01:20 PM
I have a template-based service which includes this YANG snippet:
leaf receive-traps {
type boolean;
default false;
}
The corresponding template includes this:
<?if {/receive-traps}?>
<some stuff here that enables trap processing />
<?end?>
When I create an instance of this service and set receive-traps to false, the above if condition apparently evaluates as true because the <some stuff here...> shows up.
Looking at the xpath.trace, I see it being evaluated as follows:
10-Jan-2019::15:54:54.574 template snmp-template: evaluating: string(boolean(/receive-traps))
10-Jan-2019::15:54:54.574 template snmp-template: result: true
/receive-traps is false, so this evaluates as string(false), which I assume is the string "false",
which is boolean true since it is a non-empty string. Am I interpreting this correctly? Why is the condition being cast into a string? How do I make it just treat the expression as the boolean it is?
Thanks,
-Allen
Solved! Go to Solution.
01-13-2019 06:17 AM
I guess you are only checking the existence of the receive-traps, perhaps you can change it to:
<?if {/receive-traps = 'false'}?>
01-13-2019 06:17 AM
I guess you are only checking the existence of the receive-traps, perhaps you can change it to:
<?if {/receive-traps = 'false'}?>
01-14-2019 10:14 AM
Thanks, that works. I think you must be right about it checking for existence. I would point out that is not how it's supposed to work according to the NSO Developer's Guide, which says a "conditional expression will evaluate to false when...the argument evaluates to a boolean false..."
However, this might explain why the devtools xpath command has different options for `eval`, `must`, and `when`... I'm guessing that 'if' expressions are evaluated in the same way as `xpath when` .
Thanks
01-14-2019 11:43 AM
To answer this, we have to look in the XPath specification, https://www.w3.org/TR/1999/REC-xpath-19991116/#function-boolean note the wording *a node-set is true if and only if it is non-empty".
Now, the expression /receive-traps is a path and evaluating it returns a node-set, not a single node, so boolean on a path actually asks if the path exists or not, and doesn't care what it contains.
The reason the comparison works is in the definition of equality:
If one object to be compared is a node-set and the other is a string, then the comparison will be true if and only if there is a node in the node-set such that the result of performing the comparison on the string-value of the node and the other string is true.
It is worth remembering that XPath often gives surprising results, precisely because things are often node-sets instead of nodes.
I hope you find my explanation helpful and not nit-picky, to me XPath evaluation in NSO is one of the trickier things to wrap your head around.
01-14-2019 06:43 PM
Thank you very much for the clarification. It's not nit-picky at all. In fact, that really helps to explain why it works the way it does. XPATH has definitely been the most difficult aspect of service development to understand.
01-15-2019 04:15 AM
I agree, I often avoid complex XPath and do things in python or java instead - though simple things like an if-statement I would probably leave in the template.
Speaking of python/java - when applying a template through the API any variables passed in as template variables from the programming language vill always be a scalar, never a node-set.
Discover and save your favorite ideas. Come back to expert answers, step-by-step guides, recent topics, and more.
New here? Get started with these tips. How to use Community New member guide