Exemplo n.º 1
0
 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
Exemplo n.º 2
0
 def __str__(self):
     return "\t"+Flist.__str__(self)+\
             "FlistHash - (null)\n"
Exemplo n.º 3
0
 def __init__(self):
     Flist.__init__(self)        # force constructor
Exemplo n.º 4
0
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()