Subject: [netmod] YANG XPath usage guidelines (6087bis)

From: Jernej Tuljak <[email-masked]>
Date: Thu, 03 Jul 2014 13:10:36 +0200

Hi,

some questions about YANG XPath expressions in general and as observed 
by 6087bis [1].

Does it make sense to use the 'id(object)' and 'lang(string)' XPath 
functions in YANG XPath expressions? They both imply existence of XML 
attributes, which cannot be modeled in pure YANG. Shouldn't RFC6087bis 
include a guideline for those in Section 4.5.? Is there a case where the 
mentioned XPath functions could be used?

'local-name(node-set?)', 'namespace-uri(node-set?)', 'name(node-set?)', 
'string(object?)' and 'number(object?)' are all directly reliant on 
document order when the argument evaluates to a node-set with size > 1 
and may therefore return different results for different 
implementations, like the case with 'position' and 'last'. Other 
functions may also be indirectly reliant on document order when they are 
supplied with a node-set argument which then needs to be converted into 
a string or a number as if by calling 'string(object?)' or  
'number(object?)' respectively [2]. Shouldn't this also be mentioned in 
the guidelines, since some other cases are?

Axes 'preceding-sibling' and 'following-sibling' should not be used 
unless dealing with user ordered lists or leaf-lists and I agree with 
6087bis, however document order may not be relevant when using those two 
axes (uniqueness checks). There's an example in ietf-routing module [3]:
not(/routing/ribs/rib[name=current()/preceding-sibling::connected-rib/rib-name 
and 
address-family=/routing/ribs/rib[name=current()/rib-name]/address-family])
where current() evaluates to a non-user ordered list instance. Shouldn't 
this also be mentioned in the guidelines as an acceptable corner case, 
like it is for 'preceding' and 'following'?

6087bis specifies:

    XPath expressions for 'when' statements MUST NOT reference the
    context node or any descendant nodes of the context node.

yet ietf-ipv4-unicast-routing [3] clearly does so, with it's conditional 
augments of rpc methods, where it references 'rt:address-family' which 
is a descendant of the initial context node (augmentation target or 
nearest data node ancestor). Shouldn't conditional augmentation be an 
exception to this paragraph?

6087bis specifies:

    Data nodes that use the 'int64' and 'uint64' built-in type SHOULD NOT
    be used within numeric expressions.  There are boundary conditions in
    which the translation from the YANG 64-bit type to an XPath number
    can cause incorrect results.  Specifically, an XPath 'double'
    precision floating point number cannot represent very large positive
    or negative 64-bit numbers because it only provides a total precision
    of 53 bits.  The 'int64' and 'uint64' data types MAY be used in
    numeric expressions if the value can be represented with no more than
    53 bits of precision.

In XPath specification [4], term "numeric expressions" refers to 
additive (+, -), multiplicative (*, mod, div) or unary expressions 
(sign) and does not include relational or equality expressions, so 
comparisons of int64 and uint64 data nodes do not seem to be discouraged 
by the current text. Was this intentional? Shouldn't all such numeric 
conversions be avoided?

Ladislav once mentioned [5] that YANG XPath is able to "break out of 
module containment" with an expression like
/*[local-name()='foo']
which is quite dangerous and IMO deserves mention in the guidelines. It 
should be clear that an expression is only able to reference names 
defined within the scope of a module, right? Or was "breaking out of 
module containment" intended as a feature of RFC6020 (seems more like a 
bug to me)? Completely unrelated modules should not cause unwanted side 
effects when implemented together.

[1] 
http://tools.ietf.org/html/draft-bierman-netmod-rfc6087bis-00#section-4.5
[2] http://www.w3.org/TR/1999/REC-xpath-19991116/#section-Function-Calls
[3] http://tools.ietf.org/html/draft-ietf-netmod-routing-cfg-15
[4] http://www.w3.org/TR/1999/REC-xpath-19991116/#numbers
[5] http://www.ietf.org/mail-archive/web/netmod/current/msg09623.html

Jernej

---

From: Ladislav Lhotka <[email-masked]>
Date: Mon, 07 Jul 2014 11:10:51 +0200

> mentioned XPath functions could be used?

Now that there are several proposals for standardizing (global)
attributes for use with YANG data, it might actually be useful to refer
to attributes in XPath expressions. One use case could be: "Nodes X and
Y can both be present only if at least one of them is tagged as
inactive".

But in order to be able to do this, one needs to be able to include an
attribute's namespace in the context of the XPath expression - this is
another case where the "attribute" statement (issue Y33) would be useful.
 
> like it is for 'preceding' and 'following'?

I think the following text in 6087bis should be extended to cover
"preceding-sibling" and "following-sibling" as well:

"The 'preceding' and 'following' axes MAY be used if document order is
not relevant to the outcome of the expression (e.g., check for global
uniqueness of a parameter value)."

> yet ietf-ipv4-unicast-routing [3] clearly does so, with it's

The example in sec. 3.3 of RFC 7223 does it, too.
 
> exception to this paragraph?

Yes. In fact, many of the concerns regarding "when" (see e.g. issue Y18)
don't apply if it is used under "augment" because the result of "when"
evaluation doesn't affect the context node.

> effects when implemented together.

+1

Lada

> _______________________________________________
> netmod mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/netmod

-- 
Ladislav Lhotka, CZ.NIC Labs
PGP Key ID: E74E8C0C

---

From: Juergen Schoenwaelder <[email-masked]>
Date: Mon, 7 Jul 2014 11:17:41 +0200

> another case where the "attribute" statement (issue Y33) would be useful.

I am not sure we have agreement to make attributes first class
citizens and in any case we should think carefully before stepping on
what might turn out to be a rather slippery road.

/js

-- 
Juergen Schoenwaelder           Jacobs University Bremen gGmbH
Phone: +49 421 200 3587         Campus Ring 1, 28759 Bremen, Germany
Fax:   +49 421 200 3103         <http://www.jacobs-university.de/>

---

From: Ladislav Lhotka <[email-masked]>
Date: Mon, 7 Jul 2014 11:24:18 +0200

> what might turn out to be a rather slippery road.

Sure, my comment was just a side note about one aspect related to attributes, should they ever be introduced - even if they are not first-class citizens.

Lada

---

From: Jernej Tuljak <[email-masked]>
Date: Mon, 07 Jul 2014 13:41:32 +0200

> another case where the "attribute" statement (issue Y33) would be useful.

Perhaps, but the functions I mentioned are quite specific about what 
attributes they require in order to be implemented. Do you see any use 
cases that utilize 'id' and 'lang' in the context of NETCONF/YANG? The 
first requires a DTD, if the XPath spec is to be strictly followed, and 
the second requires 'xml:lang' attributes - note that YANG does not 
support definition of identifiers that start with 'xml', so even if you 
had an "attribute" statement in YANG this would still require an 
extension, unless an attribute statement could specify it's own 
namespace and prefix (:D). I realize that XPath is only used as a 
notation in YANG, but the semantics of an arbitrary expression still 
need to be well specified.

------
Function: boolean lang(string)

The lang function returns true or false depending on whether the 
language of the context node as specified by xml:lang attributes is the 
same as or is a sublanguage of the language specified by the argument 
string. The language of the context node is determined by the value of 
the xml:lang attribute on the context node, or, if the context node has 
no xml:lang attribute, by the value of the xml:lang attribute on the 
nearest ancestor of the context node that has an xml:lang attribute. If 
there is no such attribute, then lang returns false. If there is such an 
attribute, then lang returns true if the attribute value is equal to the 
argument ignoring case, or if there is some suffix starting with - such 
that the attribute value is equal to the argument ignoring that suffix 
of the attribute value and ignoring case. For example, lang("en") would 
return true if the context node is any of these five elements:

<para xml:lang="en"/>
<div xml:lang="en"><para/></div>
<para xml:lang="EN"/>
<para xml:lang="en-us"/>

Function: node-set id(object)

The id function selects elements by their unique ID (see [5.2.1 Unique 
IDs]). When the argument to id is of type node-set, then the result is 
the union of the result of applying id to the string-value of each of 
the nodes in the argument node-set. When the argument to id is of any 
other type, the argument is converted to a string as if by a call to the 
string function; the string is split into a whitespace-separated list of 
tokens (whitespace is any sequence of characters matching the production 
S); the result is a node-set containing the elements in the same 
document as the context node that have a unique ID equal to any of the 
tokens in the list.

* id("foo") selects the element with unique ID foo

* id("foo")/child::para[position()=5] selects the fifth para child of 
the element with unique ID foo

5.2.1 Unique IDs

An element node may have a unique identifier (ID). This is the value of 
the attribute that is declared in the DTD as type ID. No two elements in 
a document may have the same unique ID. If an XML processor reports two 
elements in a document as having the same unique ID (which is possible 
only if the document is invalid) then the second element in document 
order must be treated as not having a unique ID.

NOTE: If a document does not have a DTD, then no element in the document 
will have a unique ID.
------

> uniqueness of a parameter value)."

I agree.

Jernej

---

From: Ladislav Lhotka <[email-masked]>
Date: Mon, 7 Jul 2014 13:45:50 +0200

On 07 Jul 2014, at 13:41, Jernej Tuljak <[email-masked]> wrote:

> Perhaps, but the functions I mentioned are quite specific about what attributes they require in order to be implemented. Do you see any use cases that utilize 'id' and 'lang' in the context of NETCONF/YANG? The

No, I was talking about attributes in general.

Lada

>  first requires a DTD, if the XPath spec is to be strictly followed, and the second requires 'xml:lang' attributes - note that YANG does not support definition of identifiers that start with 'xml', so even if you had an "attribute" statement in YANG this would still require an extension, unless an attribute statement could specify it's own namespace and prefix (:D). I realize that XPath is only used as a notation in YANG, but the semantics of an arbitrary expression still need to be well specified.
> 
> ------
> The lang function returns true or false depending on whether the language of the context node as specified by xml:lang attributes is the same as or is a sublanguage of the language specified by the argument string. The language of the context node is determined by the value of the xml:lang attribute on the context node, or, if the context node has no xml:lang attribute, by the value of the xml:lang attribute on the nearest ancestor of the context node that has an xml:lang attribute. If there is no such attribute, then lang returns false. If there is such an attribute, then lang returns true if the attribute value is equal to the argument ignoring case, or if there is some suffix starting with - such that the attribute value is equal to the argument ignoring that suffix of the attribute value and ignoring case. For example, lang("en") would return true if the context node is any of these five elements:
> 
> <para xml:lang="en"/>
> The id function selects elements by their unique ID (see [5.2.1 Unique IDs]). When the argument to id is of type node-set, then the result is the union of the result of applying id to the string-value of each of the nodes in the argument node-set. When the argument to id is of any other type, the argument is converted to a string as if by a call to the string function; the string is split into a whitespace-separated list of tokens (whitespace is any sequence of characters matching the production S); the result is a node-set containing the elements in the same document as the context node that have a unique ID equal to any of the tokens in the list.
> 
> * id("foo")/child::para[position()=5] selects the fifth para child of the element with unique ID foo
> 
> 5.2.1 Unique IDs
> 
> An element node may have a unique identifier (ID). This is the value of the attribute that is declared in the DTD as type ID. No two elements in a document may have the same unique ID. If an XML processor reports two elements in a document as having the same unique ID (which is possible only if the document is invalid) then the second element in document order must be treated as not having a unique ID.
> 
> NOTE: If a document does not have a DTD, then no element in the document will have a unique ID.
> ------
> 
>>