Package dsc_suite :: Package gui :: Module xmlpars
[hide private]
[frames] | no frames]

Source Code for Module dsc_suite.gui.xmlpars

  1  '''Module XMLpars 
  2  This module provides the class XMLParser especially designed for the use with the GUI. 
  3  You can create new XML files, write new data into an existing file and you can read information from a file. 
  4  There is already a search function implemented which gives back specific information. 
  5  This function can be used as a template for a more general search. 
  6   
  7  The communication interface is based on dictionaries. 
  8  @author: Tobias Heimpold 
  9  ''' 
 10  import xml.dom.minidom as DOM 
 11  import os 
 12  from dsc_suite.tools.toolpaths import FOLDER_FOR_DATA as FFDATA 
 13   
14 -class XMLParser(object):
15 """class XMLParser(object) 16 This class is the parser for the XML files. It is based on dictionary interface to the GUI. 17 Every key in a dictionary is used as a tag name in the XML file. The value is either the tag content or (when a dictionary) the next hierarchical level of the XML file. 18 """
19 - def __init__(self, source, mode):
20 """__init__ 21 - parses a XML file given by the path source or creates it 22 - mode is the tag name of the top level items 23 - root node must be named with mode+"s" 24 """ 25 self.__source = source 26 self.__mode = mode 27 if not os.path.exists(source): 28 self.createNewXML(source, mode+"s") 29 self.__tree = DOM.parse(source)
30 31
32 - def nextTopLevelTag(self, index):
33 """nextTopLevelTag(index) 34 - returns a dictionary with: 35 key ... tag name 36 value ... text in XML 37 - from the XML entry index 38 Hint: use with countTopLevelItems() to avoid index out of range exception ! 39 """ 40 root = self.__tree.firstChild 41 #get toplevelitem name 42 toplevelname = str(self.__findTopLevelItemName(self.__tree.firstChild)) 43 #get all toplevelitems 44 olddata = self.__tree.getElementsByTagName(toplevelname) 45 #get toplevelitem with index 46 datafile = olddata[index] 47 #create dictionary for all sublevel tags and values 48 dict = self.__getTag(datafile, root) 49 return dict[toplevelname]
50
51 - def countTopLevelTags(self):
52 """countTopLevelTags() 53 - returns number of toplevel items in XML file 54 """ 55 toplevelname = str(self.__findTopLevelItemName(self.__tree.firstChild)) 56 return len(self.__tree.getElementsByTagName(toplevelname))
57
58 - def writeNewData(self, dict):
59 """writeNewData(dict) 60 - writes the data from dict into the XML File 61 - Attention: XML File must exist and have a root instance. The top level name is set by parsing the XML file --> see __init__ 62 structure of dict: 63 { 64 65 <key1> : {<key2> : <value2>}, 66 <key3> : <value3> 67 } 68 - results in XML structure: 69 <root> 70 <mode> 71 <key1> 72 <key2>value2</key2> 73 </key1> 74 </mode> 75 </root> 76 """ 77 #read old data from tree 78 try: 79 toplevelname = str(self.__findTopLevelItemName(self.__tree.firstChild)) 80 rootname = str(self.__tree.firstChild.tagName) 81 olddata = self.__tree.getElementsByTagName(toplevelname) 82 except: 83 toplevelname = None 84 85 if toplevelname == "None": 86 toplevelname = self.__mode 87 rootname = self.__mode+"s" 88 if toplevelname != self.__mode: 89 raise AttributeError 90 #getting root an old data 91 92 #create new XML tree 93 doc = DOM.Document() 94 root = DOM.Element(rootname) 95 #add old data to new tree - recurrent 96 for old_top in olddata: 97 self.__newFromOldNode(old_top, root) 98 99 #adding new data - recurrent 100 for index in dict.keys(): 101 newtop = DOM.Element(toplevelname) 102 self.__newNode(dict[index], newtop) 103 root.appendChild(newtop) 104 105 #print to a pretty XML with same path --> overriding old file 106 doc.appendChild(root) 107 fobj = open(self.__source, "w") 108 print >> fobj, doc.toprettyxml() 109 fobj.close()
110
111 - def createNewXML(self, path, string):
112 """createNewXML(path, string) 113 - creates a new XMl file with the given path an adds the root instance named by string 114 """ 115 #create document instance 116 doc = DOM.Document() 117 #create root 118 root = DOM.Element(string) 119 doc.appendChild(root) 120 #write XML file 121 fobj = open(path, "w") 122 print >> fobj, doc.toprettyxml() 123 fobj.close()
124
125 - def getRootName(self):
126 """getRootName() 127 - return the name of the root instance in the XML file""" 128 return str(self.__tree.firstChild.tagName)
129
130 - def getCharacteristic(self, data, algorithm, bench, cost_criteria, characteristics):
131 """getCharacteristic(data, algorithm, bench, cost_criteria, chararcteristic) 132 - should be used with mean_values XML only !! --> see GUI for information 133 parameter: 134 - data : string 135 - algorithm : string 136 - bench : string 137 - cost_criteria : list-of-strings 138 - characteristics : list-of strings 139 - return: 140 dict with structure: 141 { 142 criteria 1 : { char1 : value , char2 : value}, 143 criteria 2 : { char1 : value, char2 : value} 144 } 145 or: {} if not found 146 """ 147 #getting XML tree 148 root = self.__tree.firstChild 149 #get main entries 150 items = root.getElementsByTagName("datafile") 151 #copy list 152 new_items = items[:] 153 #prepare search lists 154 tag_list = ["datastructure", "algorithm", "benchmark"] 155 value_list = [data, algorithm, bench] 156 #search in the XML for the specific entry 157 #first step find all items with datastructure --> new search pool 158 #second step find in new pool all items with algorithm --> new search pool 159 #third step find in new pool all items with benchmark 160 for i in range(0,len(tag_list), 1): 161 items = new_items[:] 162 new_items = [] 163 for item in items: 164 list = item.getElementsByTagName(tag_list[i]) 165 for node in list: 166 child = node.firstChild 167 text = str(child.data.strip()) 168 if text == value_list[i]: 169 new_items.append(item) 170 #now find in the entry the criteria given by list 171 #in the criteria level find characteristics given by list 172 #create dictionary for return 173 items = new_items[:] 174 chars = {} 175 for string in cost_criteria: 176 for item in items: 177 list = item.getElementsByTagName(string) 178 for criteria in list: 179 chars.update({string: {}}) 180 for char in characteristics: 181 tag = criteria.getElementsByTagName(char)[0] 182 text = tag.firstChild.data.strip() 183 chars[string].update({char:text}) 184 return chars
185
186 - def __findTopLevelItemName(self, node):
187 """findTopLevelItemNamse(self, node) 188 - finds the element and returns its tag name 189 - use for getting toplevelitem name in XML file 190 """ 191 for child in node.childNodes: 192 if child.nodeType == DOM.Node.ELEMENT_NODE: 193 if child.tagName == "datafile" or child.tagName == "plot": 194 return child.tagName 195 else: 196 continue
197
198 - def __newNode(self, todo, parent):
199 200 for key in todo.keys(): 201 if type(todo[key]) == dict: 202 newchild = DOM.Element(key) 203 self.__newNode(todo[key], newchild) 204 205 else: 206 newchild = DOM.Element(key) 207 newtext = DOM.Text() 208 newtext.data = todo[key] 209 newchild.appendChild(newtext) 210 parent.appendChild(newchild)
211
212 - def __newFromOldNode(self, node, parent):
213 """newNode(node, parent) 214 - builds a new node from the given node including its child nodes and adds it as a child to parent node 215 recurrent function ! 216 """ 217 if node.nodeType == DOM.Node.ELEMENT_NODE: 218 newnode = DOM.Element(node.tagName) 219 if node.hasChildNodes: 220 for child in node.childNodes: 221 self.__newFromOldNode(child, newnode) 222 parent.appendChild(newnode) 223 224 if node.nodeType == DOM.Node.TEXT_NODE and node.nextSibling == None and node.previousSibling == None: 225 newtext = DOM.Text() 226 newtext.data = node.data.strip() 227 parent.appendChild(newtext)
228
229 - def __getTag(self, node, parent):
230 """getTag(node, parent) 231 - both parameter are node instances of the XML file 232 - parent is obviously the parent node from node 233 - this function calls itself until node is an text node with interesting content 234 - returns dictionary: 235 {parent.tagName : node.text} 236 """ 237 #deside wether Element Node... 238 if node.nodeType == DOM.Node.ELEMENT_NODE: 239 dict = {} 240 if node.hasChildNodes: 241 #for each child node call function again 242 #--> until all information is in dict 243 for child in node.childNodes: 244 newdict = self.__getTag(child, node) 245 if node.tagName not in newdict.keys(): 246 try: 247 dict[node.tagName].update(newdict) 248 except KeyError: 249 dict[node.tagName] = {} 250 dict[node.tagName].update(newdict) 251 else: 252 dict = newdict 253 return dict 254 #...or TextNode with interesting content --> skipping whitespace tags 255 if node.nodeType == DOM.Node.TEXT_NODE and node.nextSibling == None and node.previousSibling == None: 256 #creating content of dict 257 key = str(parent.tagName) 258 text = node.data.strip() 259 text = str(text) 260 return {key: text} 261 else: 262 return {}
263