Subject: [netmod] Validation question

From: William Lupton <[email-masked]>
Date: Wed, 20 Jan 2016 14:43:17 +0000

All,

We have been experimenting with validating XML instances along the lines explained in the tutorials at http://www.yang-central.org/twiki/bin/view/Main/DSDLMappingTutorial <http://www.yang-central.org/twiki/bin/view/Main/DSDLMappingTutorial> and https://github.com/mbj4668/pyang/wiki/InstanceValidation <https://github.com/mbj4668/pyang/wiki/InstanceValidation> and we have hit a problem with identities in XPath expressions.

This is illustrated by the YANG module shown below, which is inspired by an example in RFC 6020bis, and the XML instance shown below the YANG. Note that:
The second "when" statement doesn't use a prefix on the interface type.
Shouldn't be a problem because the interface type is defined in the current module and so doesn't need a prefix?
The XML uses a prefix name of "exaug" rather than "mymod" which is used in the YANG.
Shouldn't be a problem because prefixes should be local?

Validating this instance gives the following two errors (which go away if the prefix "mymod" is used in all "when" statements and in the XML).

== Validating semantic constraints ...
--- Validity error at "/nc:data/if:interfaces/if:interface":
    Found nodes that are valid only when "if:type = 'mymod:some-new-iftype'"
--- Validity error at "/nc:data/if:interfaces-state/if:interface":
    Found nodes that are valid only when "if:type = 'some-new-iftype'"

Are we doing something wrong here, or is there a problem with how identities in XPath expressions are translated (per RFC 6110)? On the face of it it seems that identities are being treated as literal strings (but we haven't investigated this assertion).

Thanks,
William Lupton

--------

YANG:
module example-augment {
  namespace "http://example.com/augment";
  prefix mymod;
  
  import ietf-interfaces {
    prefix if;
  }
  
  identity some-new-iftype {
    base if:interface-type;
  }
  
  augment "/if:interfaces/if:interface" {
    when "if:type = 'mymod:some-new-iftype'";

    container some-new-container {
    }
  }

  augment "/if:interfaces-state/if:interface" {
    when "if:type = 'some-new-iftype'";

    container some-new-container {
    }
  }
}

XML:
<?xml version="1.0" encoding="UTF-8"?>
<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"
  xmlns:exaug="http://example.com/augment">
  <interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
    <interface>
      <name/>
      <description/>
      <type>exaug:some-new-iftype</type>
      <enabled>true</enabled>
      <link-up-down-trap-enable>enabled</link-up-down-trap-enable>
      <some-new-container xmlns="http://example.com/augment">
      </some-new-container>
    </interface>
  </interfaces>
  <interfaces-state xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
    <interface>
      <name/>
      <type>exaug:some-new-iftype</type>
      <admin-status>up</admin-status>
      <oper-status>up</oper-status>
      <if-index>1</if-index>
      <statistics>
        <discontinuity-time>2016-01-15T12:55:00Z</discontinuity-time>
      </statistics>
      <some-new-container xmlns="http://example.com/augment">
      </some-new-container>
    </interface>
  </interfaces-state>
</data>

---

From: Ladislav Lhotka <[email-masked]>
Date: Fri, 22 Jan 2016 10:32:09 +0100

Hi William,

YANG uses XPath 1.0, and so the equality tests mean *string
equality*. That's why 6087bis recommends in sec. 5.6.4:

   XPath expressions that contain a literal value representing a YANG
   identity SHOULD always include the declared prefix of the module
   where the identity is defined.

In YANG 1.1, the new XPath functions derived-from() and
derived-from-or-self() will alleviate this problem.

Lada

William Lupton <[email-masked]> writes:

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

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

---

From: William Lupton <[email-masked]>
Date: Fri, 22 Jan 2016 17:18:38 +0000

Lada,

Thanks for drawing my attention to this section. I hadn't noticed this advice.

Perhaps corresponding things need to be said about the XML?
Always use a prefix on identity values, even if the default namespace (YANG module) is the module that defined the identity.
When importing a namespace (YANG module) that contains identities that are referenced in the XML, always use the same prefix that was used within the imported module.

The need for the first of the above XML-related statements wasn't illustrated by the YANG and XML in my first message but it's illustrated by the fragments shown below.

I guess the point about derived-from() and derived-from-or-self() is that, although they still specify the identities as strings, the strings are known to be identities, so prefixes can be processed (applying defaults etc)?

Finally, I think perhaps this is a separate point (because not related to string values), but seems to be necessary to use the same prefixes for imported modules as were used within those modules. For example, if (in my example) I change the ietf-interfaces prefix from if to ifx, validation fails with an "undefined namespace prefix" error.

Cheers,
William

YANG fragment:
  identity sub-type;

  identity sub-type-a {
    base sub-type;
  }

    container some-new-container {
      leaf sub-type {
        type identityref {
          base sub-type;
        }
      }
      container sub-container {
        when "../mymod:sub-type = 'mymod:sub-type-a'";
      }
    }
  }

XML fragment (mymod prefix is necessary in order for XML to validate):
      <some-new-container xmlns="http://example.com/augment">
	<sub-type>mymod:sub-type-a</sub-type>
	<sub-container/>
      </some-new-container>

> On 22 Jan 2016, at 09:32, Ladislav Lhotka <[email-masked]> wrote:
> 
> Hi William,
>

---

From: Ladislav Lhotka <[email-masked]>
Date: Mon, 25 Jan 2016 15:01:15 +0100

> Perhaps corresponding things need to be said about the XML?

Yes, for YANG 1.0. In YANG 1.1 the string comparison of identity values
should be avoided in favour of the new XPath functions that work for any
properly qualified identity names. 

> I guess the point about derived-from() and derived-from-or-self() is
> that, although they still specify the identities as strings, the
> strings are known to be identities, so prefixes can be processed
> (applying defaults etc)?

Right. In terms of XML/XPath they are treated as qualified names (QNames).

>
> Finally, I think perhaps this is a separate point (because not related
> to string values), but seems to be necessary to use the same prefixes
> for imported modules as were used within those modules. For example,
> if (in my example) I change the ietf-interfaces prefix from if to ifx,
> validation fails with an "undefined namespace prefix" error.

Apart from string comparisons in XPath, this should never be a
problem. Can you send me (off list) your data that fail to validate?

Lada