Welcome, guest | Sign In | My Account | Store | Cart

When you parse XML using minidom, you can get a map of attributes for any element. The problem is that using the "in" operator on this map will raise an exception. These three lines of code will fix that.

Python, 4 lines
from xml.dom import minidom

if not hasattr( minidom.NamedNodeMap, '__contains__' ):
    minidom.NamedNodeMap.__contains__ = minidom.NamedNodeMap.has_key

NOTE: This recipe depends on the API for xml.dom as documented in Python 2.2 - 2.4. If in future versions getting the attributes of a Node no longer returns a NamedNodeMap, this recipe will break.

The problem is illustrated below...

>>> from xml.dom import minidom
>>> XML = '<' 'root' '><' 'myNode key1="value1" key2="value2"' '/><' '/root' '>'
>>> doc = minidom.parseString( XML )
>>> attributeMap = doc.documentElement.firstChild.attributes
>>> attributeMap.has_key('key1')
>>> 'key1' in attributeMap # Why doesn't this work!
Traceback (most recent call last):
  File "", line 1, in ?
  File "C:\Python24\lib\xml\dom\minidom.py", line 529, in __getitem__
    return self._attrs[attname_or_tuple]
KeyError: 0

This is because the map is missing the __contains__ method. After invoking this recipe, you will get correct bahavior...

>>> 'key1' in attributeMap
>>> 'key3' in attributeMap

The exception occurs because the in operator will invoke __getitem__ with successive integer indexes if __contains__ is not available. For mapping objects that lack __contains__, you will get an exception unless all of the keys are integers counting up from 0.

This recipe adds the missing method to the class. Python lets you do this without modifying the source code of the class! In this case, I just recycled the existing has_key method.

If I needed to create an entirely new method for an existing class, I could do so by importing the new module:

>>> import new
>>> def __contains__(self, key):
...     "Just an example of creating a new method..."
...     return self.has_key(key)
>>> method = new.instancemethod(__contains__, None, minidom.NamedNodeMap)
>>> minidom.NamedNodeMap.__contains__ = method
>>> 'key1' in attributeMap
Created by Walker Hale on Fri, 23 Jun 2006 (PSF)
Python recipes (4591)
Walker Hale's recipes (2)

Required Modules

Other Information and Tasks