# Dive Into Python Python for experienced programmers | Find:

## 5.11. Creating separate handlers by node type

The third useful XML processing tip involves separating your code into logical functions, based on node types and element names. Parsed XML documents are made up of various types of nodes, each represented by a Python object. The root level of the document itself is represented by a `Document` object. The `Document` then contains one or more `Element` objects (for actual XML tags), each of which may contain other `Element` objects, `Text` objects (for bits of text), or `Comment` objects (for embedded comments). Python makes it easy to write a dispatcher to separate the logic for each node type.

### Example 5.40. Class names of parsed XML objects

    >>> from xml.dom import minidom
    >>> xmldoc = minidom.parse('kant.xml')
    >>> xmldoc
    <xml.dom.minidom.Document instance at 0x01359DE8>
    >>> xmldoc.__class__
    <class xml.dom.minidom.Document at 0x01105D40>
    >>> xmldoc.__class__.__name__
    'Document'

| Assume for a moment that `kant.xml` is in the current directory.
| As we saw in Packages, the object returned by parsing an XML document is a `Document` object, as defined in the `minidom.py` in the `xml.dom` package. As we saw in Instantiating classes, `__class__` is built-in attribute of every Python object.
| Furthermore, `__name__` is a built-in attribute of every Python class, and it is a string. This string is not mysterious; it’s the same as the class name you type when you define a class yourself. (See Defining classes.)

Fine, so now we can get the class name of any particular XML node (since each XML node is represented as a Python object). How can we use this to our advantage to separate the logic of parsing each node type? The answer is `getattr`, which we first saw in Getting object references with getattr.

### Example 5.41. `parse`, a generic XML node dispatcher

        def parse(self, node):
            parseMethod = getattr(self, "parse_%s" % node.__class__.__name__)
            parseMethod(node)

| First off, notice that we’re constructing a larger string based on the class name of the node we were passed (in the `node` argument). So if we’re passed a `Document` node, we’re constructing the string `'parse_Document'`, and so forth.
| Now we can treat that string as a function name, and get a reference to the function itself using `getattr`
| Finally, we can call that function and pass the node itself as an argument. The next example shows the definitions of each of these functions.

### Example 5.42. Functions called by the `parse` dispatcher

        def parse_Document(self, node):
            self.parse(node.documentElement)

        def parse_Text(self, node):
            text = node.data
            if self.capitalizeNextWord:
                self.pieces.append(text[0].upper())
                self.pieces.append(text[1:])
                self.capitalizeNextWord = 0
            else:
                self.pieces.append(text)

        def parse_Comment(self, node):
            pass

        def parse_Element(self, node):
            handlerMethod = getattr(self, "do_%s" % node.tagName)
            handlerMethod(node)

| `parse_Document` is only ever called once, since there is only one `Document` node in an XML document, and only one `Document` object in the parsed XML representation. It simply turns around and parses the root element of the grammar file.
| `parse_Text` is called on nodes that represent bits of text. The function itself does some special processing to handle automatic capitalization of the first word of a sentence, but otherwise simply appends the represented text to a list.
| `parse_Comment` is just a `pass`, since we don’t care about embedded comments in our grammar files. Note, however, that we still need to define the function and explicitly make it do nothing. If the function did not exist, our generic `parse` function would fail as soon as it stumbled on a comment, because it would try to find the non-existent `parse_Comment` function. Defining a separate function for every node type, even ones we don’t use, allows the generic `parse` function to stay simple and dumb.
| The `parse_Element` method is actually itself a dispatcher, based on the name of the element’s tag. The basic idea is the same: take what distinguishes elements from each other (their tag names) and dispatch to a separate function for each of them. We construct a string like `'do_xref'` (for an `<xref>` tag), find a function of that name, and call it. And so forth for each of the other tag names that might be found in the course of parsing a grammar file (`<p>` tags, `<choice>` tags).

In this example, the dispatch functions `parse` and `parse_Element` simply find other methods in the same class. If your processing is very complex (or you have many different tag names), you could break up your code into separate modules, and use dynamic importing to import each module and call whatever functions you needed. Dynamic importing will be discussed in Data-Centric Programming.