Subject: [netmod] simple example of XSD-based modular augments

From: Andy Bierman <[email-masked]>
Date: Thu, 20 Nov 2008 14:57:32 -0800

Hi,

This is how yangdump handles the modular augment problem.
Can the same sort of hack be done in RelaxNG?

Andy
module test5 {

    namespace "urn:ietf:params:xml:ns:yang:test5";
    prefix "t5";

    revision 2008-11-20 {
        description "Initial revision.";
    }

    container test5 {
      list a {
        key g1;
        leaf g1 { type string; }
        leaf g2 { type string; }
      }
   }
}
module test6 {

    namespace "urn:ietf:params:xml:ns:yang:test6";
    prefix "t6";
    import test5 { prefix t5; }

    revision 2008-11-20 {
        description "Initial revision.";
    }

    augment /t5:test5/t5:a {
      leaf g3 { type int32; }
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
   xmlns="urn:ietf:params:xml:ns:yang:test5"
   targetNamespace="urn:ietf:params:xml:ns:yang:test5"
   elementFormDefault="qualified" attributeFormDefault="unqualified"
   xml:lang="en" version="2008-11-20"
   xmlns:ncx="http://netconfcentral.com/ncx"
   xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
   <xs:annotation>
      <xs:documentation>
         Converted from YANG file 'test5.yang' by yangdump version 0.9.4
         
         Module: test5
         Version: 2008-11-20
      </xs:documentation>
      <xs:appinfo>
         <ncx:source>
            /home/andy/modules/test5.yang
         </ncx:source>
      </xs:appinfo>
      <xs:appinfo>
         <ncx:revision>
            <ncx:version>2008-11-20</ncx:version>
            <ncx:description>Initial revision.</ncx:description>
         </ncx:revision>
      </xs:appinfo>
   </xs:annotation>

   <xs:element name="test5">
      <xs:annotation>
         <xs:appinfo>
            <ncx:config>true</ncx:config>
         </xs:appinfo>
      </xs:annotation>
      <xs:complexType>
         <xs:sequence>
            <xs:element name="a" minOccurs="0" maxOccurs="unbounded">
               <xs:annotation>
                  <xs:appinfo>
                     <ncx:ordered-by>system</ncx:ordered-by>
                  </xs:appinfo>
               </xs:annotation>
               <xs:complexType>
                  <xs:sequence>
                     <xs:element name="g1" type="xs:string"/>
                     <xs:element name="g2" type="xs:string"
                        minOccurs="0"/>
                     <xs:element name="__.test5.a.A__" minOccurs="0"
                        maxOccurs="unbounded" abstract="true"/>
                  </xs:sequence>
               </xs:complexType>
               <xs:key name="a_Key">
                  <xs:selector xpath="."/>
                  <xs:field xpath="g1"/>
               </xs:key>
            </xs:element>
            <xs:element name="__.test5.A__" minOccurs="0"
               maxOccurs="unbounded" abstract="true"/>
         </xs:sequence>
      </xs:complexType>
   </xs:element>

</xs:schema>
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
   xmlns="urn:ietf:params:xml:ns:yang:test6"
   targetNamespace="urn:ietf:params:xml:ns:yang:test6"
   elementFormDefault="qualified" attributeFormDefault="unqualified"
   xml:lang="en" version="2008-11-20"
   xmlns:ncx="http://netconfcentral.com/ncx"
   xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"
   xmlns:t5="urn:ietf:params:xml:ns:yang:test5">
   <xs:annotation>
      <xs:documentation>
         Converted from YANG file 'test6.yang' by yangdump version 0.9.4
         
         Module: test6
         Version: 2008-11-20
      </xs:documentation>
      <xs:appinfo>
         <ncx:source>
            /home/andy/modules/test6.yang
         </ncx:source>
      </xs:appinfo>
      <xs:appinfo>
         <ncx:revision>
            <ncx:version>2008-11-20</ncx:version>
            <ncx:description>Initial revision.</ncx:description>
         </ncx:revision>
      </xs:appinfo>
   </xs:annotation>

   <xs:element name="g3" type="xs:int" minOccurs="0"
      substitutionGroup="t5:__.test5.a.A__"/>

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

---

From: Ladislav Lhotka <[email-masked]>
Date: Thu, 20 Nov 2008 18:34:51 -0600

Hi Andy,

so this means leaving a "backdoor" in every possible place, where
external augment can be applied, right? This would be in principle
possible in RELAX NG, too, but I think it could easily break. Questions:

1. In XSD, how the two schemas get associated together if both modules
appear in <hello>? test5.xsd by itself has no pointer to test6.xsd.

2. Would it work if a third module applies a different augment to the
same place?

Lada

Andy Bierman píše v Čt 20. 11. 2008 v 14:57 -0800:
> Prostý textový dokument příloha (test5.yang)
> module test5 {
> 
> Prostý textový dokument příloha (test6.yang)
> module test6 {
> 
-- 
Ladislav Lhotka, CESNET
PGP Key ID: E74E8C0C

---

From: Andy Bierman <[email-masked]>
Date: Thu, 20 Nov 2008 17:14:29 -0800

> appear in <hello>? test5.xsd by itself has no pointer to test6.xsd.

that would be broken.
test6 must import test5 to access the substitutionGroup QName.

 From t6:

                          ^^

This will create a 't6:g3' element in the '/t5:test5/t5:a' list.

> 2. Would it work if a third module applies a different augment to the

yes.  they will each create elements in their own namespace,
as substitution elements for the target of the augment.

Andy

---

From: Ladislav Lhotka <[email-masked]>
Date: Tue, 25 Nov 2008 15:59:15 +0100

Hi,

attached are two schemas that show how the modular augment could be
handled in RELAX NG, based on Andy's test modules (also included). To
use the combined schema, the following "driver" schema is needed:
---------------------------------------------------
namespace ns1 = "urn:ietf:params:xml:ns:yang:test5"

include "test5.rnc" inherit = ns1
include "test6.rnc" inherit = ns1
---------------------------------------------------

While it looks pretty simple, the following points are important to
note:

1. The RELAX NG schema must be made completely flat, having contents of
each non-leaf element defined as a separate pattern with a name that
encodes the element's full path.

2. One difference from YANG that cannot be avoided is that the items in
the "a" list can appear interleaved in XML, for example in the order
"g1", "g3", "g2".

3. If test6.yang contained any data tree of its own, this tree would
have to be mapped to a separate schema (file). Stuff augmenting every
individual module must always be put in a separate schema.

4. Also, if there were any top-level groupings and typedefs that can be
imported by another module, they would have to be put in yet another
special schema with the "native" namespace of groupings' content removed
so that it can inherit the namespace of the importing module.

5. "Internal" augments of imported groupings can be handled in the same
way as for the external ones, using "de-namespaced" version of the
imported schema (sse 4). Caveat 2 also applies here.

6. I still don't know how to handle refinements of imported groupings
and multi-level derivation of modular types and tend to believe it is
not possible.

Cheers, Lada

---

From: Ladislav Lhotka <[email-masked]>
Date: Tue, 25 Nov 2008 16:14:56 +0100

Sorry, this last line should be 

include "test6-augment-test5.rnc" inherit = ns1

Lada

-- 
Ladislav Lhotka, CESNET
PGP Key ID: E74E8C0C