4 from xml.dom import minidom
5 from types import StringTypes, ListType
9 def __init__(self, xml = None, xsd = None):
10 self.xsd = xsd # schema
11 self.rootNode = None # root of the dom
12 self.dict = {} # dict of the rspec.
18 self.dict = self.toDict()
20 def _getText(self, nodelist):
23 if node.nodeType == node.TEXT_NODE:
27 # The rspec is comprised of 2 parts, and 1 reference:
28 # attributes/elements describe individual resources
29 # complexTypes are used to describe a set of attributes/elements
30 # complexTypes can include a reference to other complexTypes.
33 def _getName(self, node):
34 '''Gets name of node. If tag has no name, then return tag's localName'''
36 if not node.nodeName.startswith("#"):
39 elif node.attributes.has_key("name"):
40 name = node.attributes.get("name").value
44 # Attribute. {name : nameofattribute, {items: values})
45 def _attributeDict(self, attributeDom):
46 '''Traverse single attribute node. Create a dict {attributename : {name: value,}]}'''
47 node = {} # parsed dict
48 for attr in attributeDom.attributes.keys():
49 node[attr] = attributeDom.attributes.get(attr).value
53 def toDict(self, nodeDom = None):
55 convert this rspec to a dict and return it.
59 nodeDom = self.rootNode
61 elementName = nodeDom.nodeName
62 if elementName and not elementName.startswith("#"):
63 # attributes have tags and values. get {tag: value}, else {type: value}
64 node[elementName] = self._attributeDict(nodeDom)
65 #node.update(self._attributeDict(nodeDom))
66 # resolve the child nodes.
67 if nodeDom.hasChildNodes():
68 for child in nodeDom.childNodes:
69 childName = self._getName(child)
72 if not node[elementName].has_key(childName):
73 node[elementName][childName] = []
75 childdict = self.toDict(child)
76 for value in childdict.values():
77 node[elementName][childName].append(value)
78 #node[childName].append(self.toDict(child))
84 convert this rspec to an xml string and return it.
86 return self.rootNode.toxml()
89 def toprettyxml(self):
91 print this rspec in xml in a pretty format.
93 return self.rootNode.toprettyxml()
96 def parseFile(self, filename):
98 read a local xml file and store it as a dom object.
100 dom = minidom.parse(filename)
101 self.rootNode = dom.childNodes[0]
104 def parseString(self, xml):
106 read an xml string and store it as a dom object.
108 xml = xml.replace('\n', '').replace('\t', '').strip()
109 dom = minidom.parseString(xml)
110 self.rootNode = dom.childNodes[0]
113 def dict2dom(self, rdict, include_doc = False):
115 convert a dict object into a dom object.
118 def elementNode(tagname, rd):
119 element = minidom.Element(tagname)
120 for key in rd.keys():
121 if isinstance(rd[key], StringTypes):
122 element.setAttribute(key, rd[key])
123 elif isinstance(rd[key], dict):
124 child = elementNode(key, rd[key])
125 element.appendChild(child)
126 elif isinstance(rd[key], list):
128 child = elementNode(key, item)
129 element.appendChild(child)
132 node = elementNode(rdict.keys()[0], rdict.values()[0])
134 rootNode = minidom.Document()
135 rootNode.appendChild(node)
141 def parseDict(self, rdict, include_doc = True):
143 Convert a dictionary into a dom object and store it.
145 self.rootNode = self.dict2dom(rdict, include_doc)
148 def getDictsByTagName(self, tagname, dom = None):
150 Search the dom for all elements with the specified tagname
151 and return them as a list of dicts
156 doms = dom.getElementsByTagName(tagname)
157 dictlist = [self.toDict(d) for d in doms]
158 for item in dictlist:
159 for value in item.values():
163 def getDictByTagNameValue(self, tagname, value, dom = None):
165 Search the dom for the first element with the specified tagname
166 and value and return it as a dict.
171 dicts = self.getDictsByTagName(tagname, dom)
174 if rdict.has_key('name') and rdict['name'] in [value]:
180 def filter(self, tagname, attribute, blacklist = [], whitelist = [], dom = None):
182 Removes all elements where:
183 1. tagname matches the element tag
184 2. attribute matches the element attribte
185 3. attribute value is in valuelist
192 if dom.localName in [tagname] and dom.attributes.has_key(attribute):
193 if whitelist and dom.attributes.get(attribute).value not in whitelist:
194 dom.parentNode.removeChild(dom)
195 if blacklist and dom.attributes.get(attribute).value in blacklist:
196 dom.parentNode.removeChild(dom)
198 if dom.hasChildNodes():
199 for child in dom.childNodes:
200 self.filter(tagname, attribute, blacklist, whitelist, child)