def __init__(self): FstringHash.__init__(self) # force contrustor self.fileName = None # yeah, this is it ! self.doc = None # the document self.root = None # the root node self.firstCurrent = None # the first node of the tree self.current = None # the current node self.stackCurrent = Flist() # a stack used to push and pop self.current
def __str__(self): return "\t"+Flist.__str__(self)+\ "FlistHash - (null)\n"
def __init__(self): Flist.__init__(self) # force constructor
class Fconfig(FstringHash): """ This class gives you the ability to walk around and through an XML document. This document can be created from sratch, read from a file, completed and modified, and so on. You can also execute some research queries... Everything seems to be safe /~\/~\.""" def __init__(self): FstringHash.__init__(self) # force contrustor self.fileName = None # yeah, this is it ! self.doc = None # the document self.root = None # the root node self.firstCurrent = None # the first node of the tree self.current = None # the current node self.stackCurrent = Flist() # a stack used to push and pop self.current def __str__(self): return "\t"+FstringHash.__str__(self) +\ " Fconfig - File : "+str(self.fileName)+\ " - Current_Name : "+str(self.getName())+\ " - Current_Content : "+str(self.getContent())+"\n" def startXml(self, param): """/** Read an XML tree, param may be a file name or an xmlNode. */""" if isinstance(param,str): # a filename is given, parse this file self.fileName = param try: self.doc = libxml2.parseFile(param) except: return RC.RET_CANNOTACCESS param = self.doc.children # a node is given or we have one now if not isinstance(param,libxml2.xmlNode): return RC.RET_CANNOTACCESS self.root = param.doc.children self.firstCurrent = param self.current = param if self.gotoChildren() != RC.RET_OK: return RC.RET_NOTEXIST # find <evenja_name> tag and put it's content in our FstringHash if self.Find(ES.XML_NAME, False) != RC.RET_OK: return RC.RET_NONAME string = self.getContent() if string == RC.RET_NONODESELECTED: # don't need this ... return RC.RET_NONAME self.setString(string) self.resetCurrent() return RC.RET_OK def startNewXml(self, fileName = None): """/** Create a new XML tree. */""" if fileName: self.fileName = fileName else: self.fileName = None try: self.doc = libxml2.newDoc(ES.XML_VERSION) self.doc.newChild(None, ES.XML_XML, None) except: return RC.RET_CANNOTCREATE self.root = self.doc.children self.firstCurrent = self.root self.current = self.root self.setString(ES.TXT_NEW) return RC.RET_OK def endXml(self): """/** Close the XML tree. Save it if a file name exists. */""" if self.doc and self.fileName: if self.doc.saveFile(self.fileName) == -1: return RC.RET_CANNOTEND if self.doc: self.doc.freeDoc() self.doc = None self.root = None self.firstCurrent = None self.current = None self.fileName = None return RC.RET_OK def getCurrent(self): """/** Get the current node. */""" return self.current # WALKING METHODS def resetCurrent(self, fromRoot = False): """/** Set current node to the root one if fromRoot, otherwise to the first one. */""" if fromRoot: self.current = self.root else: self.current = self.firstCurrent def gotoFirst(self): """/** Go to the first node of the current branch. */""" if not self.current: return RC.RET_NONODESELECTED self.current = self.current.parent.children if self.current.type != "element": return self.gotoNext() return RC.RET_OK def gotoLast(self): """/** Go to the last node of the current branch. */""" if not self.current: return RC.RET_NONODESELECTED self.current = self.current.parent.last if self.current.type != "element": return self.gotoPrev() return RC.RET_OK def gotoNext(self): """/** Go to the next node of the current branch. */""" if not self.current: return RC.RET_NONODESELECTED if not self.current.next: return RC.RET_NOTEXIST node = self.current.next while node.type != "element" and node.next: # walk 'till you find node = node.next if node.type == "element": self.current = node return RC.RET_OK return RC.RET_NOTEXIST def gotoPrev(self): """/** Go to the previous node of the current branch. */""" if not self.current: return RC.RET_NONODESELECTED if not self.current.prev: return RC.RET_NOTEXIST node = self.current.prev while node.type != "element" and node.prev: # walk 'till you find node = node.prev if node.type == "element": self.current = node return RC.RET_OK return RC.RET_NOTEXIST def gotoChildren(self): """/** Go to the children node of the current node. */""" if not self.current: return RC.RET_NONODESELECTED if not self.current.children: return RC.RET_NOTEXIST tmp = self.current self.current = self.current.children if self.current.type == "element": return RC.RET_OK ret = self.gotoNext() if ret == RC.RET_NOTEXIST: self.current = tmp return ret def gotoParent(self): """/** Go to the parent node of the current node. */""" if not self.current: return RC.RET_NONODESELECTED if not self.current.parent: return RC.RET_NOTEXIST tmp = self.current self.current = self.current.parent if self.current.type == "element": return RC.RET_OK ret = self.gotoPrev() if ret == RC.RET_NOTEXIST: self.current = tmp return ret def Search(self, name, subTree = True): """/** Find a name, with or without tree recusivity, using preorder path. self.current is saved from not_found case */""" if not self.current: return RC.RET_NONODESELECTED bkp = self.current # save self.current while True: if self.getName() == name: return RC.RET_OK if subTree and self.current.children: # maybe deeper ?? if self.gotoChildren() == RC.RET_OK: if self.Search(name,subTree) == RC.RET_OK: return RC.RET_OK else: self.gotoParent() if RC.RET_OK !=self.gotoNext(): # maybe further ?? self.current = bkp # recover self.current return RC.RET_NOTFOUND def Find(self, name, subTree = True): """/** Find a name from th etop of the tree, with or without tree recusivity. */""" ret = self.gotoFirst() if ret != RC.RET_OK: return ret return self.Search(name,subTree) def FindNext(self, name, subTree = True): """/** Find next name, with or without tree recusivity. */""" ret = self.gotoNext() if ret != RC.RET_OK: return ret return self.Search(name,subTree) # RETRIEVE INFORMATIONS def getName(self): """/** Get the Name of the current Node. */""" if self.current: return self.current.name return RC.RET_NONODESELECTED def setName(self, name): """/** Set the Name of the current Node. */""" if not self.current: return RC.RET_NONODESELECTED self.current.setName(name) return RC.RET_OK def getContent(self): """/** Get the Content of the current Node. */""" if not self.current: return RC.RET_NONODESELECTED currentA = self.current.children if currentA: return currentA.content return ES.TXT_NULL def setContent(self, content): """/** Set the Content of the current Node. */""" if not self.current: return RC.RET_NONODESELECTED if content <> None: self.current.setContent(content) else: self.current.setContent(ES.TXT_NULL) return RC.RET_OK # CREATE ADN DELETE NODES def addChildren(self, name, content = None): """/** Create a new node (the current node is the parent). */""" if not self.current: return RC.RET_NONODESELECTED self.current.newChild(None,name,content) if self.doc and not self.root: self.root = self.doc.children self.firstCurrent = self.root self.current = self.root return RC.RET_OK def removeCurrent(self): """/** Remove the current node (recursively). After remove operation, goto the previous node if exists or to the next, or the parent*/""" str = self.getName() if str == RC.RET_NONODESELECTED or str is None: return RC.RET_NONODESELECTED if str.upper() == ES.XML_XML.upper(): # TzurTcH - case insensitive should be ok return RC.RET_OK toRemove = self.current if self.current.prev: self.gotoPrev() elif self.current.next: self.gotoNext() elif self.current.parent: self.gotoParent() # maybe it will empty this tree ... if self.root == toRemove or self.firstCurrent == toRemove or self.root.doc.children == toRemove: self.root = None self.firstCurrent = None self.current = None toRemove.unlinkNode() toRemove.freeNode() return RC.RET_OK # STACK MEMORY CAPABILITIES def pushCurrent(self): """/** Push the Current position to the stack. */""" self.stackCurrent.add(self.current) def popCurrent(self): """/** Pop the Current position from the stack. */""" if self.stackCurrent.getCount(): self.current = self.stackCurrent.removeStack()