4 from xml.dom import minidom
5 from types import StringTypes
13 def __init__(self, spec_dict):
14 sdict = self.plcToSpec(spec_dict)
15 dict.__init__(self, sdict)
17 def plcToSpec(self, spec_dict):
19 for field in self.fields:
20 plc_field = plc_fields[field]
22 if spec_dict.has_key(field):
23 spec[field] = spec_dict(field)
25 return {self.type: spec}
35 def __init__(self, xml = None, xsd = None):
36 self.xsd = xsd # schema
37 self.rootNode = None # root of the dom
38 self.dict = {} # dict of the rspec.
44 self.dict = self.toDict()
46 def _getText(self, nodelist):
49 if node.nodeType == node.TEXT_NODE:
53 # The rspec is comprised of 2 parts, and 1 reference:
54 # attributes/elements describe individual resources
55 # complexTypes are used to describe a set of attributes/elements
56 # complexTypes can include a reference to other complexTypes.
59 def _getName(self, node):
60 '''Gets name of node. If tag has no name, then return tag's localName'''
62 if not node.nodeName.startswith("#"):
65 elif node.attributes.has_key("name"):
66 name = node.attributes.get("name").value
70 # Attribute. {name : nameofattribute, {items: values})
71 def _attributeDict(self, attributeDom):
72 '''Traverse single attribute node. Create a dict {attributename : {name: value,}]}'''
73 node = {} # parsed dict
74 for attr in attributeDom.attributes.keys():
75 node[attr] = attributeDom.attributes.get(attr).value
79 def toDict(self, nodeDom = None):
81 convert this rspec to a dict and return it.
85 nodeDom = self.rootNode
87 elementName = nodeDom.nodeName
88 if elementName and not elementName.startswith("#"):
89 # attributes have tags and values. get {tag: value}, else {type: value}
90 node[elementName] = self._attributeDict(nodeDom)
91 #node.update(self._attributeDict(nodeDom))
92 # resolve the child nodes.
93 if nodeDom.hasChildNodes():
94 for child in nodeDom.childNodes:
95 childName = self._getName(child)
98 if not node[elementName].has_key(childName):
99 node[elementName][childName] = []
100 #node[childName] = []
101 childdict = self.toDict(child)
102 for value in childdict.values():
103 node[elementName][childName].append(value)
104 #node[childName].append(self.toDict(child))
110 convert this rspec to an xml string and return it.
112 return self.rootNode.toxml()
115 def toprettyxml(self):
117 print this rspec in xml in a pretty format.
119 return self.rootNode.toprettyxml()
122 def parseFile(self, filename):
124 read a local xml file and store it as a dom object.
126 dom = minidom.parse(filename)
127 self.rootNode = dom.childNodes[0]
130 def parseString(self, xml):
132 read an xml string and store it as a dom object.
134 xml = xml.replace('\n', '').replace('\t', '').strip()
135 dom = minidom.parseString(xml)
136 self.rootNode = dom.childNodes[0]
139 def dict2dom(self, rdict, include_doc = False):
141 convert a dict object into a dom object.
144 def elementNode(tagname, rd):
145 element = minidom.Element(tagname)
146 for key in rd.keys():
147 if isinstance(rd[key], StringTypes):
148 element.setAttribute(key, rd[key])
149 elif isinstance(rd[key], dict):
150 child = elementNode(key, rd[key])
151 element.appendChild(child)
152 elif isinstance(rd[key], list):
154 child = elementNode(key, item)
155 element.appendChild(child)
158 node = elementNode(rdict.keys()[0], rdict.values()[0])
160 rootNode = minidom.Document()
161 rootNode.appendChild(node)
167 def parseDict(self, rdict, include_doc = True):
169 Convert a dictionary into a dom object and store it.
171 self.rootNode = self.dict2dom(rdict, include_doc)
174 def getDictsByTagName(self, tagname, dom = None):
176 Search the dom for all elements with the specified tagname
177 and return them as a list of dicts
182 doms = dom.getElementsByTagName(tagname)
183 dictlist = [self.toDict(d) for d in doms]
184 for item in dictlist:
185 for value in item.values():