Package flickrapi :: Module xmlnode
[hide private]
[frames] | no frames]

Source Code for Module flickrapi.xmlnode

  1   
  2  '''FlickrAPI uses its own in-memory XML representation, to be able to easily 
  3  use the info returned from Flickr. 
  4   
  5  There is no need to use this module directly, you'll get XMLNode instances 
  6  from the FlickrAPI method calls. 
  7  ''' 
  8   
  9  import xml.dom.minidom 
 10   
 11  __all__ = ('XMLNode', ) 
12 13 14 -class XMLNode:
15 """XMLNode -- generic class for holding an XML node 16 17 >>> xml_str = '''<xml foo="32"> 18 ... <taggy bar="10">Name0</taggy> 19 ... <taggy bar="11" baz="12">Name1</taggy> 20 ... </xml>''' 21 >>> f = XMLNode.parse(xml_str) 22 >>> f.name 23 u'xml' 24 >>> f['foo'] 25 u'32' 26 >>> f.taggy[0].name 27 u'taggy' 28 >>> f.taggy[0]["bar"] 29 u'10' 30 >>> f.taggy[0].text 31 u'Name0' 32 >>> f.taggy[1].name 33 u'taggy' 34 >>> f.taggy[1]["bar"] 35 u'11' 36 >>> f.taggy[1]["baz"] 37 u'12' 38 39 """ 40
41 - def __init__(self):
42 """Construct an empty XML node.""" 43 self.name = "" 44 self.text = "" 45 self.attrib = {} 46 self.xml = None
47
48 - def __setitem__(self, key, item):
49 """Store a node's attribute in the attrib hash.""" 50 self.attrib[key] = item
51
52 - def __getitem__(self, key):
53 """Retrieve a node's attribute from the attrib hash.""" 54 return self.attrib[key]
55 56 @classmethod
57 - def __parse_element(cls, element, this_node):
58 """Recursive call to process this XMLNode.""" 59 60 this_node.name = element.nodeName 61 62 # add element attributes as attributes to this node 63 for i in range(element.attributes.length): 64 an = element.attributes.item(i) 65 this_node[an.name] = an.nodeValue 66 67 for a in element.childNodes: 68 if a.nodeType == xml.dom.Node.ELEMENT_NODE: 69 70 child = XMLNode() 71 # Ugly fix for an ugly bug. If an XML element <name /> 72 # exists, it now overwrites the 'name' attribute 73 # storing the XML element name. 74 if not hasattr(this_node, a.nodeName) or a.nodeName == 'name': 75 setattr(this_node, a.nodeName, []) 76 77 # add the child node as an attrib to this node 78 children = getattr(this_node, a.nodeName) 79 children.append(child) 80 81 cls.__parse_element(a, child) 82 83 elif a.nodeType == xml.dom.Node.TEXT_NODE: 84 this_node.text += a.nodeValue 85 86 return this_node
87 88 @classmethod
89 - def parse(cls, xml_str, store_xml=False):
90 """Convert an XML string into a nice instance tree of XMLNodes. 91 92 xml_str -- the XML to parse 93 store_xml -- if True, stores the XML string in the root XMLNode.xml 94 95 """ 96 97 dom = xml.dom.minidom.parseString(xml_str) 98 99 # get the root 100 root_node = XMLNode() 101 if store_xml: 102 root_node.xml = xml_str 103 104 return cls.__parse_element(dom.firstChild, root_node)
105