Subject: sec. 6 update (subtree filtering)

From: Andy Bierman <[email-masked]>
Date: Tue, 29 Mar 2005 09:08:52 -0800

Hi,

Here is my attempt to cleanup section 6.  I found a couple of issues 
(see [ed. note ] inline) which should
get separate email threads.  I think Rob is holding up prot-06 for this 
text, so we need to quickly
resolve these issues:
   I025: Filter by namespace only (retrieve entire data model without 
knowing the top-level element(s))
   I026: subtree filter top-level elements should not be considered in 
the same sibling set. They should
            be independent to allow retrieval of multiple partial data 
models

thanks,
Andy

6.  Subtree Filtering

6.1  Overview

   XML subtree filtering is a mechanism that allows an application to
   select particular XML subtrees to include in the <rpc-reply> for a
   <get> or <get-config> operation.  A small set of filters for
   inclusion, simple content exact-match, and selection is provided,
   which allows some useful, but also very limited selection mechanisms.
   The agent does not need to utilize any data-model specific semantics
   during processing, allowing for simple and centralized implementation
   strategies.

   Conceptually, a subtree filter is comprised of zero or more element
   subtrees, which represent the filter selection criteria.  At each
   containment level within a subtree, the set of sibling nodes is
   logically processed by the server to determine if its subtree (and
   path to the root) are included in the filter output.

   All elements present in a particular subtree within a filter must 
   match associated nodes present in the server's conceptual data model.
   XML namespaces may be specified (via 'xmlns' declarations) within the
   filter data model.  If so, the declared namespace must first exactly
   match a namespace supported by the server.  Note that prefix values
   for qualified namespaces are not relevant when comparing filter 
   elements to elements in the underlying data model.  Only data 
   associated with a specified namespace will be included in the 
   filter output.  

   Each node specified in a subtree filter represents an inclusive
   filter.  Only associated nodes in underlying data model(s) within
   the specified configuration datastore on the server are selected 
   by the filter.  A node must exactly match the namespace and absolute 
   path name of the filter data, except the filter absolute path name is 
   adjusted to start from the layer below <filter>.  

   Response messages contain only the subtrees selected by the filter.
   Any selection criteria that were present in the request, within a
   particular selected subtree, is also included in the response.
   Note that some elements expressed in the filter as leaf nodes
   will be expanded (i.e., subtrees included) in the filter output.
   Specific data instances are not duplicated in the response in the
   event the request contains multiple filter subtree expressions which
   select the same data.

6.2  Subtree Filter Components

   A subtree filter is comprised of XML elements and their XML
   attributes.  There are five types of components that may be 
   present in a subtree filter:
     - Namespace Selection
     - Attribute Match Expressions
     - Containment Nodes
     - Selection Nodes
     - Content Match Nodes

6.2.1 Namespace Selection

   If namespaces are used then the filter output will only include
   elements from the specified namespace.  A namespace is considered
   to match (for filter purposes) if the content of the 'xmlns'
   attributes are the same in the filter and the underlying data model.
   Note that namespace selection cannot be used by itself.
   At least one element must be specified in the filter in order for 
   any elements to selected in the filter output.

   Example:

     <filter type="subtree">
       <top xmlns="http://example.com/schema/1.2/config"/>
     </filter>
				   
   In this example the 'top' element is a selection node, and only
   this node and any child nodes (from the underlying data model) in 
   the 'http://example.com/schema/1.2/config' namespace will be 
   included in the filter output.

   [ed. - It would be nice to allow filter by namespace only,
    so the NMS does not have to know the top-level elements
    in the namespace (e.g., 'top' in our examples).  

    Perhaps:

     <filter type="namespace">
       http://example.com/schema/1.2/config
     </filter>
   ]
  
6.2.2 Attribute Match Expressions

   An attribute which appears in a subtree filter is part of
   an "attribute match expression".  Any number of (unqualified 
   or qualified) XML attributes may be present in any type of 
   filter node.  In addition to the selection criteria normally 
   applicable to that node, the selected data must have matching 
   values for every attribute specified in the node.  If an element 
   is not defined to include a specified attribute, then it is not 
   selected in the filter output.

   Example:

     <filter type="subtree">
       <t:top xmlns:t="http://example.com/schema/1.2/stats">       
         <t:interfaces>
           <t:interface t:ifName="eth0"/>
         </t:interfaces>
       </t:top>
     </filter>

   In this example the 'top', 'interfaces' and 'interface' elements are 
   containment nodes, and 'ifName' is an attribute match expression.  
   Only nodes in the 'http://example.com/schema/1.2/config' namespace, 
   which match the absolute path '/top/interfaces/interface', and
   the 'interface' element has an 'ifName' attribute defined with the 
   value 'eth0', will be included in the filter output, 

6.2.3  Containment Nodes

   Nodes which contain child elements within a subtree filter
   are called "containment nodes".  Each child element can be
   any type of node, including another containment node.  For
   each containment node specified in a subtree filter, all
   data model instances which exactly match the specified 
   namespaces, absolute path, and any attribute match expressions 
   within this node, are included in the filter output.

   Example:

     <filter type="subtree">
       <top xmlns="http://example.com/schema/1.2/config">
         <users/>
       </top>
     </filter>

   In this example the 'top', element is a containment node, and 
   the 'users' element is a selection node.  Only nodes in the 
   'http://example.com/schema/1.2/config' namespace, which match the 
   absolute path '/top/users' will be included in the filter output.

6.2.2  Selection Nodes

   An empty leaf node within a filter is called a "selection node",
   and it represents an "explicit selection" filter on the underlying
   data model.  Presence of any selection nodes within a set of sibling
   nodes will cause the filter to select the specified subtree(s),
   and suppress automatic selection of the entire set of sibling nodes
   in the underlying data model.  For filtering purposes, an empty
   leaf node can be declared with either an empty tag (e.g., <foo/>) 
   or with explicit start and end tags (e.g., <foo>  </foo>).  Any
   whitespace characters are ignored in this form.

   Example:

     <filter type="subtree">
       <top xmlns="http://example.com/schema/1.2/config">
         <users/>
       </top>
     </filter>

   In this example the 'top' element is a containment node, and 
   the 'users' element is a selection node.  Only nodes in the 
   'http://example.com/schema/1.2/config' namespace, which match the 
   absolute path '/top/users' will be included in the filter output.

6.2.5  Content Match Nodes

   A leaf node which contains simple content is called a "content
   match node".  It is used to select some or all of its sibling 
   nodes for filter output, and represents an exact-match filter on 
   the leaf node element content.  The following constraints apply to 
   content match nodes:

   o A content match node must not contain nested elements (i.e., 
     must resolve to a simpleType in XSD).  
   o Multiple content match nodes (i.e., sibling nodes) are logically
     combined in an "AND" expression.
   o Filtering of mixed content is not supported.  
   o Filtering of list content is not supported.
   o Filtering of whitespace only content is not supported.
   o A content match node must contain non-whitespace characters.
     An empty element (e.g., <foo>  </foo>) will interpreted as a
     selection node (e.g., <foo/>).  
   o Leading and trailing whitespace characters are ignored, but any 
     whitespace characters within a block of text characters are not 
     ignored or modified.

   If all specified sibling content match nodes in a subtree filter
   expression are 'true', then the filter output nodes are selected 
   in the following manner:

   o  Each content match node in the sibling set is included in 
      the filter output.
   o  If any containment nodes are present in the sibling set then
      they are processed further, and included if any nested filter
      criteria is also met.
   o  If any selection nodes are present in the sibling set then all
      of them are included in the filter output.  
   o  Otherwise (i.e., there are no selection or containment nodes
      in the filter sibling set) all the nodes defined at this level
      in the underlying data model (and their subtrees, if any) are
      returned in the filter output.

   If any of the sibling content match node tests are 'false', then no
   further filter processing is performed on that sibling set, and none
   of the sibling subtrees are selected by the filter, including the
   content match node(s).

   Example:

     <filter type="subtree">
       <top xmlns="http://example.com/schema/1.2/config">
         <users>
           <user>
             <name>fred</name>
           </user>
         </users>
       </top>
     </filter>

   In this example the 'users' and 'user' nodes are both containment
   nodes, and 'name' is a content match node.  Since no sibling nodes
   of 'name' are specified (and therefore no containment or selection 
   nodes) all of the sibling nodes of 'name' are returned in the
   filter output.  Only nodes in the 'http://example.com/schema/1.2/config' 
   namespace, which match the absolute path '/top/users/user', and
   for which the 'name' element is equal to 'fred', will be included in 
   the filter output.

6.3  Subtree Filter Processing

   The filter output (the set of selected nodes) is initially empty.

   Each subtree filter can contain one or more data model fragments,
   which represent portions of the data model which should be selected
   (with all child nodes) in the filter output.

   Each subtree data fragment is compared by the server to the internal
   data models supported by the server.  If the entire subtree
   data-fragment filter (starting from the root to the innermost element
   specified in the filter) exactly matches a corresponding portion of
   the supported data model, then that node and all its children are
   included in the result data.

   The server processes all nodes with the same parent node (sibling
   set) together, starting from the root to the leaf nodes.  The root
   elements in the filter are considered to be in the same sibling set
   (assuming they are in the same namespace), even though they do not
   have a common parent.

   [ed.  I think the paragraph above is broken. The top level should
    be a special case -- each top level element should be independent,
    in order to allow partial retrival from multiple data models in
    the same <get> or <get-config> operation.]

   For each sibling set, the server determines which nodes are included
   (or potentially included) in the filter output, and which sibling
   subtrees are excluded (pruned) from the filter output.  The server
   first determines which types of nodes are present in the sibling set,
   and processes the nodes according to the rules for their type.  If
   any nodes in the sibling set are selected, then the process is
   recursively applied to the sibling sets of each selected node.  The
   algorithm continues until all sibling sets in all subtrees specified
   in the filter have been processed.

6.4  Subtree Filtering Examples

6.4.1  No filter

   Leaving out the filter on the get operation returns the entire data
   model.

     <rpc message-id="101"
          xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
       <get/>
     </rpc>

     <rpc-reply message-id="101"
          xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
       <data>
         <!-- ... entire set of data returned ... -->
       </data>
     </rpc-reply>

6.4.2  Empty filter

   An empty filter will select nothing because no content match or
   selection nodes are present.  This is not an error.  The filter type
   attribute used in these examples is discussed further in Section 7.1.

     <rpc message-id="101"
          xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
       <get>
         <filter type="subtree">
         </filter>
       </get>
     </rpc>

     <rpc-reply message-id="101"
          xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
       <data>
       </data>
     </rpc-reply>

6.4.3  Select the entire <users> subtree

   This filter in this example contains one selection node (<users>), so
   just that subtree is selected by the filter.  This example represents
   the fully-populated <users> data model in most of the filter examples
   that follow.  In a real data model, the 'company-info' would not
   likely be returned with the list of users for a particular host or
   network.

   NOTE: The filtering and configuration examples used in this document
   appear in the namespace "http://example.com/schema/1.2/config".  The
   root element of this namespace is <top>.  The <top> element and its
   descendents represent an example configuration data model only.

     <rpc message-id="101"
          xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
       <get-config>
         <source>
           <running/>
         </source>
         <filter type="subtree">
           <top xmlns="http://example.com/schema/1.2/config">
             <users/>
           </top>
         </filter>
       </get-config>
     </rpc>

     <rpc-reply message-id="101"
          xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
       <data>
         <top xmlns="http://example.com/schema/1.2/config">
           <users>
             <user>
               <name>root</name>
               <type>superuser</type>
               <full-name>Charlie Root</full-name>
               <company-info>
                 <dept>1</dept>
                 <id>1</id>
               </company-info>
             </user>
             <user>
               <name>fred</name>
               <type>admin</type>
               <full-name>Fred Flintstone</full-name>
               <company-info>
                 <dept>2</dept>
                 <id>2</id>
               </company-info>
             </user>
             <user>
               <name>barney</name>
               <type>admin</type>
               <full-name>Barney Rubble</full-name>
               <company-info>
                 <dept>2</dept>
                 <id>3</id>
               </company-info>
             </user>
           </users>
         </top>
       </data>
     </rpc-reply>

   The following filter request would have produced the same result, but
   only because the container <users> defines one child element (<user>)

     <rpc message-id="101"
          xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
       <get-config>
         <source>
           <running/>
         </source>
         <filter type="subtree">
           <top xmlns="http://example.com/schema/1.2/config">
             <users>
               <user/>
             </users>
           </top>
         </filter>
       </get-config>
     </rpc>

6.4.4  Select all <name> elements within the <users> subtree

   This filter contains two containment nodes (<users>, <user>), and one
   selector node (<name>).  All instances of the <name> element in the
   same sibling set are selected in the filter output.  The manager may
   need to know that <name> is used as an instance identifier in this
   particular data structure, but the server does not need to know that
   meta-data in order to process the request.

     <rpc message-id="101"
          xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
       <get-config>
         <source>
           <running/>
         </source>
         <filter type="subtree">
           <top xmlns="http://example.com/schema/1.2/config">
             <users>
               <user>
                 <name/>
               </user>
             </users>
           </top>
         </filter>
       </get-config>
     </rpc>

     <rpc-reply message-id="101"
          xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
       <data>
         <top xmlns="http://example.com/schema/1.2/config">
           <users>
             <user>
               <name>root</name>
             </user>
             <user>
               <name>fred</name>
             </user>
             <user>
               <name>barney</name>
             </user>
           </users>
         </top>
       </data>
     </rpc-reply>

6.4.5  One specific <user> entry

   This filter contains two containment nodes (<users>, <user>) and one
   content match node (<name>).  All instances of the sibling set
   containing <name>, for which the value of <name> equals "fred", are
   selected in the filter output.

     <rpc message-id="101"
          xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
       <get-config>
         <source>
           <running/>
         </source>
         <filter type="subtree">
           <top xmlns="http://example.com/schema/1.2/config">
             <users>
               <user>
                 <name>fred</name>
               </user>
             </users>
           </top>
         </filter>
       </get-config>
     </rpc>

     <rpc-reply message-id="101"
          xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
       <data>
         <top xmlns="http://example.com/schema/1.2/config">
           <users>
             <user>
               <name>fred</name>
               <type>admin</type>
               <full-name>Fred Flintstone</full-name>
               <company-info>
                 <dept>2</dept>
                 <id>2</id>
               </company-info>
             </user>
           </users>
         </top>
       </data>
     </rpc-reply>

6.4.6  Specific elements from a specific <user> entry

   This filter contains two containment nodes (<users>, <user>), one
   content match node (<name>), and two selector nodes (<type>,
   <full-name>).  All instances of the <type> and <full-name> elements
   in the same sibling set containing <name>, for which the value of
   <name> equals "fred", are selected in the filter output.  The
   <company-info> element is not included because the sibling set
   contains selection nodes.

     <rpc message-id="101"
          xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
       <get-config>
         <source>
           <running/>
         </source>
         <filter type="subtree">
           <top xmlns="http://example.com/schema/1.2/config">
             <users>
               <user>
                 <name>fred</name>
                 <type/>
                 <full-name/>
               </user>
             </users>
           </top>
         </filter>
       </get-config>
     </rpc>

     <rpc-reply message-id="101"
          xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
       <data>
         <top xmlns="http://example.com/schema/1.2/config">
           <users>
             <user>
               <name>fred</name>
               <type>admin</type>
               <full-name>Fred Flintstone</full-name>
             </user>
           </users>
         </top>
       </data>
     </rpc-reply>

6.4.7  Multiple Subtrees

   This filter contains three subtrees (name=root, fred, barney)

   The "root" subtree filter contains two containment nodes (<users>,
   <user>), one content match node (<name>), and one selector node
   (<company-info>).  The subtree selection criteria is met, and just
   the company-info subtree for "root" is selected in the filter output.

   The "fred" subtree filter contains three containment nodes (<users>,
   <user>, <company-info>), one content match node (<name>), and one
   selector node (<id>).  The subtree selection criteria is met, and
   just the <id> element within the company-info subtree for "fred" is
   selected in the filter output.

   The "barney" subtree filter contains three containment nodes
   (<users>, <user>, <company-info>), two content match nodes (<name>,
   <type>), and one selector node (<dept>).  The subtree selection
   criteria is not met because user "barney" is not a "superuser", and
   the entire subtree for "barney" (including its parent <user> entry)
   is excluded from the filter output.

     <rpc message-id="101"
          xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
       <get-config>
         <source>
           <running/>
         </source>
         <filter type="subtree">
           <top xmlns="http://example.com/schema/1.2/config">
             <users>
               <user>
                 <name>root</name>
                 <company-info/>
               </user>
               <user>
                 <name>fred</name>
                 <company-info>
                   <id/>
                 </company-info>
               </user>
               <user>
                 <name>barney</name>
                 <type>superuser</type>
                 <company-info>
                   <dept/>
                 </company-info>
               </user>
             </users>
           </top>
         </filter>
       </get-config>
     </rpc>

     <rpc-reply message-id="101"
          xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
       <data>
         <top xmlns="http://example.com/schema/1.2/config">
           <users>
             <user>
               <name>root</name>
               <company-info>
                 <dept>1</dept>
                 <id>1</id>
               </company-info>
             </user>
             <user>
               <name>fred</name>
               <company-info>
                 <id>2</id>
               </company-info>
             </user>
           </users>
         </top>
       </data>
     </rpc-reply>

6.4.8  Elements with attribute naming

   In this example, the filter contains one containment node
   (<interfaces>), one attribute match expression (ifName), and one
   selector node (<interface>).  All instances of the <interface>
   subtree which have an ifName attribute equal to "eth0" are selected
   in the filter output.  The filter data elements and attributes must
   be qualified because the ifName attribute will not be considered part
   of the 'schema/1.2' namespace if it is unqualified.

     <rpc message-id="101"
          xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
       <get>
         <filter type="subtree">
           <t:interfaces xmlns:t="http://example.com/schema/1.2/stats">
             <t:interface t:ifName="eth0"/>
           </t:interfaces>
         </filter>
       </get>
     </rpc>

     <rpc-reply message-id="101"
          xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
       <data>
         <top xmlns="http://example.com/schema/1.2/config">
           <t:interfaces xmlns:t="http://example.com/schema/1.2/stats">
             <t:interface t:ifName="eth0">
               <t:ifInOctets>45621</t:ifInOctets>
               <t:ifOutOctets>774344</t:ifOutOctets>
             </t:interface>
           </t:interfaces>
         </top>
       </data>
     </rpc-reply>

   If ifName were a child node instead of an attribute, then the
   following request would produce similar results.

     <rpc message-id="101"
          xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
       <get>
         <filter type="subtree">
           <interfaces xmlns="http://example.com/schema/1.2/stats">
             <interface>
               <ifName>eth0</ifName>
             </interface>
           </interfaces>
         </filter>
       </get>
     </rpc>

[end - sec. 6]