[Dev OpenGP] [43] Just working... |
[ Thread Index |
Date Index
| More opengp.tuxfamily.org/development Archives
]
Revision: 43
Author: alband85
Date: 2009-03-16 17:01:00 +0100 (Mon, 16 Mar 2009)
Log Message:
-----------
Just working... or not
Modified Paths:
--------------
trunk/src/DomElementMethods/ElementMethods.py
trunk/src/DomElementMethods/__init__.py
trunk/src/DomElementMethods-test.py
Modified: trunk/src/DomElementMethods/ElementMethods.py
===================================================================
--- trunk/src/DomElementMethods/ElementMethods.py 2009-03-16 09:35:37 UTC (rev 42)
+++ trunk/src/DomElementMethods/ElementMethods.py 2009-03-16 16:01:00 UTC (rev 43)
@@ -1,224 +1,200 @@
#!/usr/bin/python
# -*- coding: utf-8 -*
-from xml.dom.minidom import *
-from xml.dom import InvalidAccessErr
+from lxml.etree import *
+from copy import deepcopy
-ATTR_BLOCK="block"
-ATTR_ID="id"
+ATTR_BLOCK = "block"
+ATTR_ID = "id"
-def getAttributes(self):
- """
- Returns a sorted array containing the element's attributes and their values but the 'block' attribute.
- This provides a convenient way to test the equality beween two elements' attributes and values :
- (e1.getAttributes() == e2.getAttributes) <=> Excluding the 'block' attribute, e1 and e2 have same attributes with same values.
- """
- attrs=[]
- if self.hasAttributes():
- children=self.attributes
- for i in range(children.length):
- if children.item(i).name != ATTR_BLOCK:
- attrs.append([children.item(i).name, self.getAttribute(children.item(i).name)])
- attrs.sort()
- return attrs
+class OgpElement(ElementBase):
+
+ __text = ElementBase(self).text
+ def __getText(self):
+ return self.__text
+ def __setText(self, text):
+ self.delElements()
+ self.__text = text
+ text = property(__getText, __setText)
-def getBlocking(self):
- """
- A more convenient way to access the 'block' special attribute.
- """
- if (not self.hasAttribute(ATTR_BLOCK)):
- return False
- else:
- return bool(self.getAttribute(ATTR_BLOCK))
+ def __getAttributes(self):
+ res = dict()
+ for key in self.attrib:
+ res[key] = self.attrib[key]
+ try:
+ del res[ATTR_BLOCK]
+ except:
+ pass
+ return res
+ attributes = property(__getAttributes)
-def setBlocking(self,blocking):
- """
- Sets the 'block' special attribute.
- """
- self.__oldSetAttribute(ATTR_BLOCK,blocking)
+ def __getBlocking(self):
+ """
+ A more convenient way to access the 'block' special attribute.
+ """
+ b = self.get(ATTR_BLOCK)
+ if b is None:
+ return False
+ else:
+ return bool(b)
-def getText(self):
- """
- Returns the first (should be the only one) Text node's data
- """
- if self.hasChildNodes():
- children=self.childNodes
- for i in range(children.length):
- if children.item(i).nodeType == Node.TEXT_NODE:
- return children.item(i).data
- return None
+ def __setBlocking(self, blocking):
+ """
+ Sets the 'block' special attribute.
+ """
+ assert isinstance(blocking, bool)
+ if blocking:
+ self.attrib[ATTR_BLOCK] = str(blocking)
+ else:
+ try:
+ del self.attrib[ATTR_BLOCK]
+ except:
+ pass
+ blocking = property(__getBlocking, __setBlocking)
-def setText(self,text):
- """
- Deletes every CDATASection or Text child and appends a new CDATASection containing the text.
- Every Element child will be deleted by appendChild()
- """
- self.delText()
- textNode = Text()
- textNode.data = text
- self.appendChild(textNode)
+ def delElements(self):
+ """
+ Removes any Text or CDATASection child
+ """
+ for e in self:
+ self.remove(e)
-def appendText(self,text):
- """
- Appends a new Text containing the text
- Every Element child will be deleted by appendChild()
- """
- textNode = Text()
- textNode.data = text
- self.appendChild(textNode)
+ def __checkUnicity(self, elt):
+ """
+ Checks if no child element has the same name and the same attributes,
+ """
+ assert isinstance(elt, OgpElement)
+ for e in self:
+ if e.tag == elt.tag and e.attributes == elt.attributes:
+ return False
+ return True
-def delText(self):
- """
- Removes any Text child
- """
- if self.hasChildNodes():
- children=self.childNodes
- for i in range(children.length):
- if children.item(i).nodeType == Node.TEXT_NODE:
- self.removeChild(children.item(i))
+ def append(self, newChild):
+ """
+ Works as the standard function, but :
+ - If newChild is an Element, checks unicity before adding, and deletes every Text or CDATASection
+ - If newChild is a Text , deletes every Element child, adds it and the normalize().
+ """
+ assert isinstance(newChild, OgpElement)
+ if (not self.__checkUnicity(newChild)):raise OgpXmlError('append: element is not unique')
+ self.text = None
+ ElementBase.append(self, newChild)
-def delElements(self):
- """
- Removes any Text or CDATASection child
- """
- if self.hasChildNodes():
- children=self.childNodes
- for i in range(children.length):
- if children.item(i).nodeType == Node.ELEMENT_NODE:
- self.removeChild(children.item(i))
+ def insert(self, index, newChild):
+ """
+ Works as the standard function, but :
+ - If newChild is an Element, checks unicity before adding, and deletes every Text or CDATASection
+ - If newChild is a Text , deletes every Element child, adds it and the normalize().
+ """
+ assert isinstance(newChild, OgpElement)
+ assert isinstance(index, int)
-def checkUnicity(self, elt):
- """
- Checks if no child element has the same name and the same attributes,
- """
- if self.hasChildNodes():
- children=self.childNodes
- for i in range(children.length):
- if children.item(i).nodeType == Node.ELEMENT_NODE and children.item(i).tagName == elt.tagName and children.item(i).getAttributes() == elt.getAttributes():
- return False
- return True
+ if (not self.__checkUnicity(newChild)):raise OgpXmlError('insert: element is not unique')
+ self.text = None
+ ElementBase.insert(self, index, element)
-def appendChild(self, newChild):
- """
- Works as the standard function, but :
- - If newChild is an Element, checks unicity before adding, and deletes every Text or CDATASection
- - If newChild is a Text , deletes every Element child, adds it and the normalize().
- """
- if newChild.nodeType == Node.ELEMENT_NODE:
- if (not self.__checkUnicity(newChild)):raise InvalidAccessErr
- self.delText()
- self.__oldAppendChild(newChild)
- elif newChild.nodeType == Node.TEXT_NODE or newChild.nodeType == Node.CDATA_SECTION_NODE:
- self.delElements()
- self.__oldAppendChild(newChild)
- self.normalize()
- else:
- self.__oldAppendChild(newChild)
+ def extend(self, elements):
+ for element in elements:
+ assert isinstance(element, OgpElement)
+ if (not self.__checkUnicity(element)):raise OgpXmlError('extend: element is not unique')
+ ElementBase.append(self, element)
-def insertBefore(self, newChild, refChild):
- """
- Works as the standard function, but :
- - If newChild is an Element, checks unicity before adding, and deletes every Text or CDATASection
- - If newChild is a Text , deletes every Element child, adds it and the normalize().
- """
- if newChild.nodeType == Node.ELEMENT_NODE:
- if (not self.__checkUnicity(newChild)):raise InvalidAccessErr
- self.delText()
- self.__oldInsertBefore(newChild, refChild)
- elif newChild.nodeType == Node.TEXT_NODE or newChild.nodeType == Node.CDATA_SECTION_NODE:
- self.delElements()
- self.__oldInsertBefore(newChild, refChild)
- self.normalize()
- else:
- self.__oldInsertBefore(newChild, refChild)
+ def set(self, name, value):
+ assert isinstance(name, str)
+ assert isinstance(value, str)
+ #Computation of new attribute list
+ newattrs=self.attributes
+ newattrs[name] = value
+
+ #check if no brother element has the future attribute set
+ parent = self.getparent()
+ if parent is not None:
+ for br in parent:
+ if br is not self and br.tag == self.tag and br.attributes == newattrs:
+ raise OgpXmlError('set: element would no more be unique')
+ self.attrib[name] = value
-def setAttribute(self, name, value):
+ def merge(self, peer):
+ """
+ Merges self with peer. peer is considered as the "child" conf (LDAP speaking), so that it has precendence on self.
+ See plugin documentation for further details on the algorithm
+ """
+ assert isinstance(peer, OgpElement)
- #Computation of new attribute list
- newattrs=self.getAttributes()
- if not self.hasAttribute(name):
- #if attribute doesn't exist yet, just add it
- newattrs.append([name, value])
- newattrs.sort()
- else: # replace it !
- for i, attr in enumerate(newattrs):
- if attr[1] == name:
- newattrs[i] = [name, value]
- break
-
- #check if no brother element has the future attribute set
- parent = self.parentNode
- if parent is not None and parent.nodeType == Node.ELEMENT_NODE:
- brothers = parent.childNodes
- for i in range(brothers.length):
- br=brothers.item(i)
- if br.nodeType == Node.ELEMENT_NODE and not br.isSameNode(self) and br.tagName == self.tagName and br.getAttributes() == newattrs:
- raise InvalidAccessErr
- self.__oldSetAttribute(name, value)
+ #if self and peer are not exactly the same (i.e. same name and same attributes),
+ #raise OgpXmlError.
+ if self.tag != peer.tag or self.attributes != peer.attributes:
+ raise OgpXmlError('merge: peer has not same name or attributes')
+
+ #Nodes must have same content. If not, raise OgpXmlError
+ if not ((self.text is None) ^ (peer.text is not None)):
+ raise OgpXmlError('merge: peer has not same type of content')
-def merge(self, peer):
- """
- Merges self with peer. peer is considered as the "child" conf (LDAP speaking), so that it has precendence on self.
- See plugin documentation for further details on the algorithm
- """
- #if self and peer are not exactly the same (i.e. same name and same attributes),
- #raise InvalidAccessErr.
- if self.tagName != peer.tagName or self.getAttributes() != peer.getAttributes():
- raise InvalidAccessErr
-
- #Nodes must have same content. If not, raise InvalidAccessErr
- if (self.getText() is None and peer.getText() is not None) or (self.getText() is not None and peer.getText() is None):
- raise InvalidAccessErr
+ #if blocking, stop here
+ if self.blocking:return
- #First case : nodes contains Text
- if self.getText() is not None:
- self.setText(peer.getText())
- return
- else: #Second Case : nodes contains nodes
- self.reorder_ids(peer)
-
- selfCommon=dict()
+ #First case : nodes contains Text
+ if self.text is not None:
+ self.text = peer.text
+ return
+ else: #Second Case : nodes contains nodes
+ self.__reorder_ids(peer)
+
+ selfCommon=dict()
- peerNotCommon=[]
- peerCommon=dict()
+ peerNotCommon=[]
+ peerCommon=dict()
- for i in range(self.childNodes.length):
- selfE = self.childNodes.item(i)
- for j in range(peer.childNodes.length):
- peerE = peer.childNodes.item(j)
- if selfE.tagName == peerE.tagName and selfE.getAttributes() == peerE.getAttributes():
- selfCommon[[selfE.tagName, selfE.getAttributes()]] = selfE
+ for selfE in self:
+ for peerE in peer:
+ if selfE.tag == peerE.tag and selfE.attributes == peerE.attributes:
+ selfCommon[(selfE.tag, str(selfE.attributes))] = selfE
- for i in range(peer.childNodes.length):
- peerE = peer.childNodes.item(i)
- common = False
- for j in range(self.childNodes.length):
- selfE = self.childNodes.item(j)
- if peerE.tagName == selfE.tagName and peerE.getAttributes() == selfE.getAttributes():
- peerCommon[[peerE.tagName, peerE.getAttributes()]] = peerE
- common = True
- if not common:
- peerNotCommon.append(peerE)
-
- #add peer children wich are not in common
- for e in peerNotCommon:
- self.appendChild(e.clone(deep))
+ for peerE in peer:
+ common = False
+ for selfE in self:
+ if peerE.tag == selfE.tag and peerE.attributes == selfE.attributes:
+ peerCommon[(peerE.tag, str(peerE.attributes))] = peerE
+ common = True
+ if not common:
+ peerNotCommon.append(peerE)
+
+ #add peer children wich are not in common
+ for e in peerNotCommon:
+ self.append(deepcopy(e))
- #merge common children
- for k, e in selfCommon.iteritems():
- e.merge(peerCommon[k].clone(deep))
+ #merge common children
+ for k, e in selfCommon.iteritems():
+ e.merge(deepcopy(peerCommon[k]))
-def reorder_ids(self, peer):
- peerMaxId = 0
- if peer.hasChildNodes() and self.hasChildNodes:
- for i in range(peer.childNodes.length):
- e=peer.childNodes.item(i)
- if e.nodeType == Node.ELEMENT_NODE and e.hasAttribute(ATTR_ID) and int(e.getAttribute(ATTR_ID)) > peerMaxId:
- peerMaxId = int(e.getAttribute(ATTR_ID))
+ def __reorder_ids(self, peer):
+ assert isinstance(peer, OgpElement)
- for i in range(self.childNodes.length):
- e=self.childNodes.item(i)
- if e.nodeType == Node.ELEMENT_NODE and e.hasAttribute(ATTR_ID):
- e.setAttribute(ATTR_ID, str(int(e.getAttribute(ATTR_ID)) + peerMaxId + 1))
+ peerMaxId = 0
+ if len(peer) > 0 and len(self) > 0:
+ for e in peer:
+ id = e.get(ATTR_ID)
+ if id is not None and int(id) > peerMaxId:
+ peerMaxId = int(id)
+ for e in self:
+ id = e.get(ATTR_ID)
+ if id is not None:
+ e.set(ATTR_ID, str(int(id)) + peerMaxId + 1)
+
+ def toString(self):
+ return tostring(self)
+
+class OgpXmlError(Exception):
+ def __init__(self, value):
+ assert isinstance(value, str)
+ self.value = value
+
+ def __str__(self):
+ return repr(self.value)
+
+class OgpElementClassLookup(PythonElementClassLookup):
+ def lookup(self, document, element):
+ return OgpElement # defined elsewhere
+
Modified: trunk/src/DomElementMethods/__init__.py
===================================================================
--- trunk/src/DomElementMethods/__init__.py 2009-03-16 09:35:37 UTC (rev 42)
+++ trunk/src/DomElementMethods/__init__.py 2009-03-16 16:01:00 UTC (rev 43)
@@ -1,31 +1,9 @@
#!/usr/bin/python
# -*- coding: utf-8 -*
-from xml.dom.minidom import *
from ElementMethods import *
+from lxml.etree import *
-Element.getAttributes=getAttributes
-
-Element.getBlocking=getBlocking
-Element.setBlocking=setBlocking
-
-Element.setText=setText
-Element.getText=getText
-Element.appendText=appendText
-Element.delText=delText
-
-Element.delElements=delElements
-
-Element.__checkUnicity=checkUnicity
-
-Element.__oldAppendChild=Element.appendChild
-Element.appendChild=appendChild
-
-Element.__oldInsertBefore=Element.insertBefore
-Element.insertBefore=insertBefore
-
-Element.__oldSetAttribute=Element.setAttribute
-Element.setAttribute=setAttribute
-
-Element.merge=merge
-Element.reorder_ids=reorder_ids
+OGP_PARSER = XMLParser()
+OGP_PARSER.set_element_class_lookup(ElementDefaultClassLookup(element=OgpElement))
+Element = OGP_PARSER.makeelement
Modified: trunk/src/DomElementMethods-test.py
===================================================================
--- trunk/src/DomElementMethods-test.py 2009-03-16 09:35:37 UTC (rev 42)
+++ trunk/src/DomElementMethods-test.py 2009-03-16 16:01:00 UTC (rev 43)
@@ -1,14 +1,74 @@
#!/usr/bin/python
# -*- coding: utf-8 -*
-from xml.dom.minidom import *
-import DomElementMethods
+from lxml.etree import *
+from DomElementMethods import *
-obj = Element("test")
-a = Element("a")
-obj.appendChild(a)
-b = Element("b")
-obj.appendChild(b)
-a2 = Element("a")
-a.setAttribute("a","a")
-obj.appendChild(a2)
-a2.setAttribute("a","a")
+obj = Element("rootelement")
+obj2 = Element("rootelement")
+
+print "------ BLOCKING ------"
+print obj.toString()
+obj.blocking = True
+print obj.toString()
+obj.blocking = False
+print obj.toString()
+print "------- ADD --------"
+elt = Element("inserted")
+elt2 = Element("inserted")
+obj.append(elt)
+try:
+ obj.append(elt2)
+except OgpXmlError:
+ print "crash"
+
+print obj.toString()
+
+print "------ DEL -------"
+print obj.toString()
+obj.delElements()
+print obj.toString()
+
+print "------ EXTEND -------"
+print obj.toString()
+try:
+ obj.extend([elt, elt2])
+except:
+ print "crash"
+print obj.toString()
+obj.delElements()
+elt3 = Element("pouet3")
+obj.extend([elt, elt3])
+print obj.toString()
+
+print "--------- MERGE ----------"
+print (obj.text is None)
+print (obj2.text is None)
+obj.delElements()
+obj2.delElements()
+obj.append(elt)
+obj2.append(elt3)
+print obj.toString()
+print obj2.toString()
+obj2.merge(obj)
+print tostring(obj2)
+
+print " Avec du texte maintenant"
+obj3 = Element("AAA")
+obj4 = Element("AAA")
+obj3.text = "pouet"
+obj4.text = "I'm not dead"
+print tostring(obj3)
+print tostring(obj4)
+obj4.merge(obj3)
+print tostring(obj3)
+print tostring(obj4)
+
+print " -------SETTEXT----------"
+obj.delElements()
+obj.append(elt)
+print obj.toString()
+obj.text = "toto"
+print obj.text
+print obj.toString()
+
+