4 from xml.dom import minidom
5 from types import StringTypes
9 def __init__(self, xml = None, xsd = None):
13 self.parse_string(xml)
16 def _getText(self, nodelist):
19 if node.nodeType == node.TEXT_NODE:
23 # The rspec is comprised of 2 parts, and 1 reference:
24 # attributes/elements describe individual resources
25 # complexTypes are used to describe a set of attributes/elements
26 # complexTypes can include a reference to other complexTypes.
29 def _getName(self, node):
30 '''Gets name of node. If tag has no name, then return tag's localName'''
32 if not node.nodeName.startswith("#"):
35 elif node.attributes.has_key("name"):
36 name = node.attributes.get("name").value
39 # Attribute. {name : nameofattribute, {items: values})
40 def _attributeDict(self, attributeDom):
41 '''Traverse single attribute node. Create a dict {attributename : {name: value,}]}'''
42 node = {} # parsed dict
43 for attr in attributeDom.attributes.keys():
44 node[attr] = attributeDom.attributes.get(attr).value
48 def toDict(self, nodeDom = None):
50 convert this rspec to a dict and return it.
54 nodeDom = self.rootNode
56 elementName = nodeDom.nodeName
57 if elementName and not elementName.startswith("#"):
58 # attributes have tags and values. get {tag: value}, else {type: value}
59 node[elementName] = self._attributeDict(nodeDom)
60 #node.update(self._attributeDict(nodeDom))
61 # resolve the child nodes.
62 if nodeDom.hasChildNodes():
63 for child in nodeDom.childNodes:
64 childName = self._getName(child)
67 if not node[elementName].has_key(childName):
68 node[elementName][childName] = []
70 childdict = self.toDict(child)
71 for value in childdict.values():
72 node[elementName][childName].append(value)
73 #node[childName].append(self.toDict(child))
78 convert this rspec to an xml string and return it.
80 return self.rootNode.toxml()
82 def toprettyxml(self):
84 print this rspec in xml in a pretty format.
86 return self.rootNode.toprettyxml()
88 def parseFile(self, filename):
90 read a local xml file and store it as a dom object.
92 dom = minidom.parse(filename)
93 self.rootNode = dom.childNodes[0]
96 def parseString(self, xml):
98 read an xml string and store it as a dom object.
100 xml = xml.replace('\n', '').replace('\t', '').strip()
101 dom = minidom.parseString(xml)
102 self.rootNode = dom.childNodes[0]
104 def dict2dom(self, rdict, include_doc = False):
106 convert a dict object into a dom object.
109 def elementNode(tagname, rd):
110 element = minidom.Element(tagname)
111 for key in rd.keys():
112 if isinstance(rd[key], StringTypes):
113 element.setAttribute(key, rd[key])
114 elif isinstance(rd[key], dict):
115 child = elementNode(key, rd[key])
116 element.appendChild(child)
117 elif isinstance(rd[key], list):
119 child = elementNode(key, item)
120 element.appendChild(child)
123 node = elementNode(rdict.keys()[0], rdict.values()[0])
125 rootNode = minidom.Document()
126 rootNode.appendChild(node)
131 def parseDict(self, rdict, include_doc = True):
133 Convert a dictionary into a dom object and store it.
135 self.rootNode = self.dict2dom(rdict, include_doc)
138 def getDictsByTagName(self, tagname, dom = None):
140 Search the dom for all elements with the specified tagname
141 and return them as a list of dicts
146 doms = dom.getElementsByTagName(tagname)
147 dictlist = [self.toDict(d) for d in doms]
148 for item in dictlist:
149 for value in item.values():