1.1 --- a/libxml2dom/__init__.py Sun May 15 13:48:37 2005 +0000
1.2 +++ b/libxml2dom/__init__.py Sun May 15 14:30:10 2005 +0000
1.3 @@ -1,7 +1,7 @@
1.4 #!/usr/bin/env python
1.5
1.6 """
1.7 -DOM wrapper around libxml2.
1.8 +DOM wrapper around libxml2, specifically the libxml2mod Python extension module.
1.9 """
1.10
1.11 __version__ = "0.2"
1.12 @@ -15,12 +15,17 @@
1.13 parseFile as Node_parseFile, \
1.14 toString as Node_toString, toStream as Node_toStream, \
1.15 toFile as Node_toFile
1.16 -import sys
1.17 +import weakref
1.18
1.19 # NOTE: Consider a generator instead.
1.20
1.21 class NamedNodeMap(object):
1.22
1.23 + """
1.24 + A wrapper around Node objects providing DOM and dictionary convenience
1.25 + methods.
1.26 + """
1.27 +
1.28 def __init__(self, node):
1.29 self.node = node
1.30
1.31 @@ -50,7 +55,7 @@
1.32 pass
1.33
1.34 def values(self):
1.35 - return [Node(_node) for _node in Node_attributes(self.node.as_native_node()).values()]
1.36 + return [Node(_node, self.ownerDocument) for _node in Node_attributes(self.node.as_native_node()).values()]
1.37
1.38 def keys(self):
1.39 return [(attr.namespaceURI, attr.localName) for attr in self.values()]
1.40 @@ -66,15 +71,17 @@
1.41
1.42 class Node(object):
1.43
1.44 - def __init__(self, node, ownerElement=None, doctype=None):
1.45 + """
1.46 + A DOM-style wrapper around libxml2mod objects.
1.47 + """
1.48 +
1.49 + def __init__(self, node, ownerDocument=None):
1.50 self._node = node
1.51 + self.ownerDocument = ownerDocument
1.52
1.53 def as_native_node(self):
1.54 return self._node
1.55
1.56 - def _ownerDocument(self):
1.57 - return Node(Node_ownerDocument(self._node))
1.58 -
1.59 def _nodeType(self):
1.60 return Node_nodeType(self._node)
1.61
1.62 @@ -82,7 +89,7 @@
1.63
1.64 # NOTE: Consider a generator instead.
1.65
1.66 - return [Node(_node) for _node in Node_childNodes(self._node)]
1.67 + return [Node(_node, self.ownerDocument) for _node in Node_childNodes(self._node)]
1.68
1.69 def _attributes(self):
1.70 return NamedNodeMap(self)
1.71 @@ -109,10 +116,10 @@
1.72 return Node_parentNode(self._node)
1.73
1.74 def _previousSibling(self):
1.75 - return Node(Node_previousSibling(self._node))
1.76 + return Node(Node_previousSibling(self._node), self.ownerDocument)
1.77
1.78 def _nextSibling(self):
1.79 - return Node(Node_nextSibling(self._node))
1.80 + return Node(Node_nextSibling(self._node), self.ownerDocument)
1.81
1.82 def hasAttributeNS(self, ns, localName):
1.83 return Node_hasAttributeNS(self._node, ns, localName)
1.84 @@ -127,10 +134,10 @@
1.85 return Node_getAttribute(self._node, name)
1.86
1.87 def getAttributeNodeNS(self, ns, localName):
1.88 - return Node(Node_getAttributeNodeNS(self._node, ns, localName))
1.89 + return Node(Node_getAttributeNodeNS(self._node, ns, localName), self.ownerDocument)
1.90
1.91 def getAttributeNode(self, localName):
1.92 - return Node(Node_getAttributeNode(self._node, localName))
1.93 + return Node(Node_getAttributeNode(self._node, localName), self.ownerDocument)
1.94
1.95 def setAttributeNS(self, ns, name, value):
1.96 Node_setAttributeNS(self._node, ns, name, value)
1.97 @@ -145,10 +152,10 @@
1.98 Node_setAttributeNode(self._node, name, node)
1.99
1.100 def createElementNS(self, ns, name):
1.101 - return Node(Node_createElementNS(self._node, ns, name))
1.102 + return Node(Node_createElementNS(self._node, ns, name), self.ownerDocument)
1.103
1.104 def createElement(self, name):
1.105 - return Node(Node_createElement(self._node, name))
1.106 + return Node(Node_createElement(self._node, name), self.ownerDocument)
1.107
1.108 def createAttributeNS(self, ns, name):
1.109 # Returns a special temporary node.
1.110 @@ -159,34 +166,34 @@
1.111 return Node_createAttribute(self._node, name)
1.112
1.113 def createTextNode(self, value):
1.114 - return Node(Node_createTextNode(self._node, value))
1.115 + return Node(Node_createTextNode(self._node, value), self.ownerDocument)
1.116
1.117 def createComment(self, value):
1.118 - return Node(Node_createComment(self._node, value))
1.119 + return Node(Node_createComment(self._node, value), self.ownerDocument)
1.120
1.121 def importNode(self, node, deep):
1.122 if hasattr(node, "as_native_node"):
1.123 - return Node(Node_importNode(self._node, node.as_native_node(), deep))
1.124 + return Node(Node_importNode(self._node, node.as_native_node(), deep), self.ownerDocument)
1.125 else:
1.126 - return Node(Node_importNode_DOM(self._node, node, deep))
1.127 + return Node(Node_importNode_DOM(self._node, node, deep), self.ownerDocument)
1.128
1.129 def insertBefore(self, tmp, oldNode):
1.130 if hasattr(tmp, "as_native_node"):
1.131 - return Node(Node_insertBefore(self._node, tmp.as_native_node(), oldNode.as_native_node()))
1.132 + return Node(Node_insertBefore(self._node, tmp.as_native_node(), oldNode.as_native_node()), self.ownerDocument)
1.133 else:
1.134 - return Node(Node_insertBefore(self._node, tmp, oldNode.as_native_node()))
1.135 + return Node(Node_insertBefore(self._node, tmp, oldNode.as_native_node()), self.ownerDocument)
1.136
1.137 def replaceChild(self, tmp, oldNode):
1.138 if hasattr(tmp, "as_native_node"):
1.139 - return Node(Node_replaceChild(self._node, tmp.as_native_node(), oldNode.as_native_node()))
1.140 + return Node(Node_replaceChild(self._node, tmp.as_native_node(), oldNode.as_native_node()), self.ownerDocument)
1.141 else:
1.142 - return Node(Node_replaceChild(self._node, tmp, oldNode.as_native_node()))
1.143 + return Node(Node_replaceChild(self._node, tmp, oldNode.as_native_node()), self.ownerDocument)
1.144
1.145 def appendChild(self, tmp):
1.146 if hasattr(tmp, "as_native_node"):
1.147 - return Node(Node_appendChild(self._node, tmp.as_native_node()))
1.148 + return Node(Node_appendChild(self._node, tmp.as_native_node()), self.ownerDocument)
1.149 else:
1.150 - return Node(Node_appendChild(self._node, tmp))
1.151 + return Node(Node_appendChild(self._node, tmp), self.ownerDocument)
1.152
1.153 def removeChild(self, tmp):
1.154 if hasattr(tmp, "as_native_node"):
1.155 @@ -194,9 +201,6 @@
1.156 else:
1.157 Node_removeChild(self._node, tmp)
1.158
1.159 - #doctype defined in __init__
1.160 - #ownerElement defined in __init__
1.161 - ownerDocument = property(_ownerDocument)
1.162 childNodes = property(_childNodes)
1.163 value = data = nodeValue = property(_nodeValue)
1.164 name = nodeName = property(_nodeName)
1.165 @@ -204,7 +208,7 @@
1.166 namespaceURI = property(_namespaceURI)
1.167 prefix = property(_prefix)
1.168 localName = property(_localName)
1.169 - parentNode = property(_parentNode)
1.170 + ownerElement = parentNode = property(_parentNode)
1.171 nodeType = property(_nodeType)
1.172 attributes = property(_attributes)
1.173 previousSibling = property(_previousSibling)
1.174 @@ -220,7 +224,26 @@
1.175 # NOTE: To be finished.
1.176
1.177 def xpath(self, expr, variables=None, namespaces=None):
1.178 - return [Node(_node) for _node in Node_xpath(self._node, expr, variables, namespaces)]
1.179 + return [Node(_node, self.ownerDocument) for _node in Node_xpath(self._node, expr, variables, namespaces)]
1.180 +
1.181 +# Document housekeeping mechanisms.
1.182 +
1.183 +class Document(Node):
1.184 +
1.185 + "A class providing document-level housekeeping."
1.186 +
1.187 + def __init__(self, node):
1.188 + self._node = node
1.189 + self.weakref_ownerDocument = weakref.ref(self)
1.190 +
1.191 + def _ownerDocument(self):
1.192 + return self.weakref_ownerDocument()
1.193 +
1.194 + def __del__(self):
1.195 + print "Freeing document", self._node
1.196 + libxml2mod.xmlFreeDoc(self._node)
1.197 +
1.198 + ownerDocument = property(_ownerDocument)
1.199
1.200 # Utility functions.
1.201
1.202 @@ -228,7 +251,7 @@
1.203 return None
1.204
1.205 def createDocument(namespaceURI, localName, doctype):
1.206 - return Node(Node_createDocument(namespaceURI, localName, doctype))
1.207 + return Document(Node_createDocument(namespaceURI, localName, doctype))
1.208
1.209 def parse(stream_or_string):
1.210 if hasattr(stream_or_string, "read"):
1.211 @@ -238,13 +261,13 @@
1.212 return parseFile(stream_or_string)
1.213
1.214 def parseFile(s):
1.215 - return Node(Node_parseFile(s))
1.216 + return Document(Node_parseFile(s))
1.217
1.218 def parseString(s):
1.219 - return Node(Node_parseString(s))
1.220 + return Document(Node_parseString(s))
1.221
1.222 def parseURI(uri):
1.223 - return Node(Node_parseURI(uri))
1.224 + return Document(Node_parseURI(uri))
1.225
1.226 def toString(node, encoding=None):
1.227 return Node_toString(node.as_native_node(), encoding)