Next / Previous / Contents / TCC Help System / NM Tech homepage

4.6. findNames(): Recursive tree walker

This function finds all element and attribute names in a given subtree of the schema's DOM tree, and adds entries for each name to the nameTable dictionary.

pyrang
def findNames(node, args, nameTable):
    """Find element and attribute names in a subtree.

      [ (node is an et.Element) and
        (args is an Args object) and
        (nameTable is a dictionary whose keys are the Python
        names for elements and attributes, and each corresponding
        value is the XML name) ->
          nameTable  :=  nameTable with Python/XML name pairs added
              from the subtree rooted at node, with the names
              prefixed by args.prefix ]
    """

In an RNG schema, we are looking for elements of these two forms:

  <element name="N">...
   <attribute name="N">...

Therefore, all we have to do is check the node's name to see if it is either element or attribute, and in those cases add the name to nameTable. The logic that builds the Python equivalent of the XML name, and prepends args.prefix, is in Section 4.7, “addName(): Add one name to the name table”.

pyrang
    #-- 1
    # [ if node.tag is ELEMENT_N or ATTRIBUTE_N ->
    #     nameTable  :=  nameTable with an entry added with a
    #         the Python equivalent of node's "name" attribute as
    #         the key, and node's "name" attribute as the value
    #   else -> I ]
    if  node.tag == ELEMENT_N:
        eltName = node.attrib[NAME_A]
        addName(nameTable, args, eltName, "N")
    elif  node.tag == ATTRIBUTE_N:
        attrName = node.attrib[NAME_A]
        addName(nameTable, args, attrName, "A")

That takes care of extracting names from node itself. To recursively add names from its subtree, we iterate over node's children.

pyrang
    #-- 2
    # [ nameTable  :=  nameTable with new element and attribute
    #       names added from children of node ]
    for child in node:
        findNames(child, args, nameTable)