4 from xml.dom import minidom
8 def __init__(self, xml = None, xsd = None):
9 self.xsd = xsd # schema
10 self.rootNode = None # root of the dom
11 self.dict = {} # dict of the rspec.
17 self.dict = self.toDict()
19 def _getText(self, nodelist):
22 if node.nodeType == node.TEXT_NODE:
26 # The rspec is comprised of 2 parts, and 1 reference:
27 # attributes/elements describe individual resources
28 # complexTypes are used to describe a set of attributes/elements
29 # complexTypes can include a reference to other complexTypes.
32 def _getName(self, node):
33 '''Gets name of node. If tag has no name, then return tag's localName'''
35 if not node.nodeName.startswith("#"):
38 elif node.attributes.has_key("name"):
39 name = node.attributes.get("name").value
43 # Attribute. {name : nameofattribute, {items: values})
44 def _attributeDict(self, attributeDom):
45 '''Traverse single attribute node. Create a dict {attributename : {name: value,}]}'''
46 node = {} # parsed dict
47 for attr in attributeDom.attributes.keys():
48 node[attr] = attributeDom.attributes.get(attr).value
52 def toDict(self, nodeDom = None):
54 convert this rspec to a dict and return it.
58 nodeDom = self.rootNode
60 elementName = nodeDom.nodeName
61 if elementName and not elementName.startswith("#"):
62 # attributes have tags and values. get {tag: value}, else {type: value}
63 node[elementName] = self._attributeDict(nodeDom)
64 #node.update(self._attributeDict(nodeDom))
65 # resolve the child nodes.
66 if nodeDom.hasChildNodes():
67 for child in nodeDom.childNodes:
68 childName = self._getName(child)
71 if not node[elementName].has_key(childName):
72 node[elementName][childName] = []
74 childdict = self.toDict(child)
75 for value in childdict.values():
76 node[elementName][childName].append(value)
77 #node[childName].append(self.toDict(child))
83 convert this rspec to an xml string and return it.
85 return self.rootNode.toxml()
88 def toprettyxml(self):
90 print this rspec in xml in a pretty format.
92 return self.rootNode.toprettyxml()
95 def parseFile(self, filename):
97 read a local xml file and store it as a dom object.
99 dom = minidom.parse(filename)
100 self.rootNode = dom.childNodes[0]
103 def parseString(self, xml):
105 read an xml string and store it as a dom object.
107 xml = xml.replace('\n', '').replace('\t', '').strip()
108 dom = minidom.parseString(xml)
109 self.rootNode = dom.childNodes[0]
112 def dict2dom(self, rdict, include_doc = False):
114 convert a dict object into a dom object.
117 def elementNode(tagname, rd):
118 element = minidom.Element(tagname)
119 for key in rd.keys():
120 if isinstance(rd[key], StringTypes):
121 element.setAttribute(key, rd[key])
122 elif isinstance(rd[key], dict):
123 child = elementNode(key, rd[key])
124 element.appendChild(child)
125 elif isinstance(rd[key], list):
127 child = elementNode(key, item)
128 element.appendChild(child)
131 node = elementNode(rdict.keys()[0], rdict.values()[0])
133 rootNode = minidom.Document()
134 rootNode.appendChild(node)
140 def parseDict(self, rdict, include_doc = True):
142 Convert a dictionary into a dom object and store it.
144 self.rootNode = self.dict2dom(rdict, include_doc)
147 def getDictsByTagName(self, tagname, dom = None):
149 Search the dom for all elements with the specified tagname
150 and return them as a list of dicts
155 doms = dom.getElementsByTagName(tagname)
156 dictlist = [self.toDict(d) for d in doms]
157 for item in dictlist:
158 for value in item.values():
162 def getDictByTagNameValue(self, tagname, value, dom = None):
164 Search the dom for the first element with the specified tagname
165 and value and return it as a dict.
170 dicts = self.getDictsByTagName(tagname, dom)
173 if rdict.has_key('name') and rdict['name'] in [value]:
179 def filter(self, tagname, attribute, valuelist, dom = None):
181 Removes all elements where:
182 1. tagname matches the element tag
183 2. attribute matches the element attribte
184 3. attribute value is in valuelist
191 if dom.localName in [tagname] and dom.attributes.has_key(attribute) and \
192 dom.attributes.get(attribute).value in valuelist:
193 dom.parentNode.removeChild(dom)
195 if dom.hasChildNodes():
196 for child in dom.childNodes:
197 self.filter(tagname, attribute, valuelist, child)