1 #!/usr/bin/env python 2 3 """ 4 DOM wrapper around libxml2. 5 """ 6 7 __version__ = "0.2" 8 9 import xml.dom 10 import libxml2 11 from libxml2dom.macrolib import * 12 from libxml2dom.macrolib import \ 13 createDocument as Node_createDocument, \ 14 parseString as Node_parseString, parseURI as Node_parseURI, \ 15 parseFile as Node_parseFile, \ 16 toString as Node_toString, toStream as Node_toStream, \ 17 toFile as Node_toFile 18 import sys 19 20 # NOTE: Consider a generator instead. 21 22 class NamedNodeMap(object): 23 24 def __init__(self, node): 25 self.node = node 26 27 def getNamedItem(self, name): 28 return self.node.getAttributeNode(name) 29 30 def getNamedItemNS(self, ns, localName): 31 return self.node.getAttributeNodeNS(ns, localName) 32 33 def setNamedItem(self, node): 34 self.node.setAttributeNode(node.name, node) 35 36 def setNamedItemNS(self, node): 37 self.node.setAttributeNodeNS(node.namespaceURI, node.localName, node) 38 39 def __getitem__(self, name): 40 return self.getNamedItem(name) 41 42 def __setitem__(self, name, node): 43 if name == node.nodeName: 44 self.setNamedItem(node) 45 else: 46 raise KeyError, name 47 48 def __delitem__(self, name): 49 # NOTE: To be implemented. 50 pass 51 52 def values(self): 53 return [Node(_node) for _node in Node_attributes(self.node.as_native_node()).values()] 54 55 def keys(self): 56 return [(attr.namespaceURI, attr.localName) for attr in self.values()] 57 58 def items(self): 59 return [((attr.namespaceURI, attr.localName), attr) for attr in self.values()] 60 61 def __repr__(self): 62 return str(self) 63 64 def __str__(self): 65 return "{%s}" % ",\n".join(["%s : %s" % (repr(key), repr(value)) for key, value in self.items()]) 66 67 class Node(object): 68 69 def __init__(self, node, ownerElement=None, doctype=None): 70 self._node = node 71 72 def as_native_node(self): 73 return self._node 74 75 def _ownerDocument(self): 76 return Node(Node_ownerDocument(self._node)) 77 78 def _nodeType(self): 79 return Node_nodeType(self._node) 80 81 def _childNodes(self): 82 83 # NOTE: Consider a generator instead. 84 85 return [Node(_node) for _node in Node_childNodes(self._node)] 86 87 def _attributes(self): 88 return NamedNodeMap(self) 89 90 def _namespaceURI(self): 91 return Node_namespaceURI(self._node) 92 93 def _nodeValue(self): 94 return Node_nodeValue(self._node) 95 96 def _prefix(self): 97 return Node_prefix(self._node) 98 99 def _nodeName(self): 100 return Node_nodeName(self._node) 101 102 def _tagName(self): 103 return Node_tagName(self._node) 104 105 def _localName(self): 106 return Node_localName(self._node) 107 108 def _parentNode(self): 109 return Node_parentNode(self._node) 110 111 def _previousSibling(self): 112 return Node(Node_previousSibling(self._node)) 113 114 def _nextSibling(self): 115 return Node(Node_nextSibling(self._node)) 116 117 def hasAttributeNS(self, ns, localName): 118 return Node_hasAttributeNS(self._node, ns, localName) 119 120 def hasAttribute(self, name): 121 return Node_hasAttribute(self._node, name) 122 123 def getAttributeNS(self, ns, localName): 124 return Node_getAttributeNS(self._node, ns, localName) 125 126 def getAttribute(self, name): 127 return Node_getAttribute(self._node, name) 128 129 def getAttributeNodeNS(self, ns, localName): 130 return Node(Node_getAttributeNodeNS(self._node, ns, localName)) 131 132 def getAttributeNode(self, localName): 133 return Node(Node_getAttributeNode(self._node, localName)) 134 135 def setAttributeNS(self, ns, name, value): 136 Node_setAttributeNS(self._node, ns, name, value) 137 138 def setAttribute(self, name, value): 139 Node_setAttribute(self._node, name, value) 140 141 def setAttributeNodeNS(self, ns, name, node): 142 Node_setAttributeNodeNS(self._node, ns, name, node) 143 144 def setAttributeNode(self, name, node): 145 Node_setAttributeNode(self._node, name, node) 146 147 def createElementNS(self, ns, name): 148 return Node(Node_createElementNS(self._node, ns, name)) 149 150 def createElement(self, name): 151 return Node(Node_createElement(self._node, name)) 152 153 def createAttributeNS(self, ns, name): 154 # Returns a special temporary node. 155 return Node_createAttributeNS(self._node, ns, name) 156 157 def createAttribute(self, name): 158 # Returns a special temporary node. 159 return Node_createAttribute(self._node, name) 160 161 def createTextNode(self, value): 162 return Node(Node_createTextNode(self._node, value)) 163 164 def createComment(self, value): 165 return Node(Node_createComment(self._node, value)) 166 167 def importNode(self, node, deep): 168 if hasattr(node, "as_native_node"): 169 return Node(Node_importNode(self._node, node.as_native_node(), deep)) 170 else: 171 return Node(Node_importNode_DOM(self._node, node, deep)) 172 173 def insertBefore(self, tmp, oldNode): 174 if hasattr(tmp, "as_native_node"): 175 return Node(Node_insertBefore(self._node, tmp.as_native_node(), oldNode.as_native_node())) 176 else: 177 return Node(Node_insertBefore(self._node, tmp, oldNode.as_native_node())) 178 179 def replaceChild(self, tmp, oldNode): 180 if hasattr(tmp, "as_native_node"): 181 return Node(Node_replaceChild(self._node, tmp.as_native_node(), oldNode.as_native_node())) 182 else: 183 return Node(Node_replaceChild(self._node, tmp, oldNode.as_native_node())) 184 185 def appendChild(self, tmp): 186 if hasattr(tmp, "as_native_node"): 187 return Node(Node_appendChild(self._node, tmp.as_native_node())) 188 else: 189 return Node(Node_appendChild(self._node, tmp)) 190 191 def removeChild(self, tmp): 192 if hasattr(tmp, "as_native_node"): 193 Node_removeChild(self._node, tmp.as_native_node()) 194 else: 195 Node_removeChild(self._node, tmp) 196 197 #doctype defined in __init__ 198 #ownerElement defined in __init__ 199 ownerDocument = property(_ownerDocument) 200 childNodes = property(_childNodes) 201 value = data = nodeValue = property(_nodeValue) 202 name = nodeName = property(_nodeName) 203 tagName = property(_tagName) 204 namespaceURI = property(_namespaceURI) 205 prefix = property(_prefix) 206 localName = property(_localName) 207 parentNode = property(_parentNode) 208 nodeType = property(_nodeType) 209 attributes = property(_attributes) 210 previousSibling = property(_previousSibling) 211 nextSibling = property(_nextSibling) 212 213 #def isSameNode(self, other): 214 # return self._node.nodePath() == other._node.nodePath() 215 216 #def __eq__(self, other): 217 # return self._node.nodePath() == other._node.nodePath() 218 219 # 4DOM extensions to the usual PyXML API. 220 # NOTE: To be finished. 221 222 def xpath(self, expr, variables=None, namespaces=None): 223 return [Node(_node) for _node in Node_xpath(self._node, expr, variables, namespaces)] 224 225 # Utility functions. 226 227 def createDocumentType(localName, publicId, systemId): 228 return None 229 230 def createDocument(namespaceURI, localName, doctype): 231 return Node(Node_createDocument(namespaceURI, localName, doctype)) 232 233 def parse(stream_or_string): 234 if hasattr(stream_or_string, "read"): 235 stream = stream_or_string 236 return parseString(stream.read()) 237 else: 238 return parseFile(stream_or_string) 239 240 def parseFile(s): 241 return Node(Node_parseFile(s)) 242 243 def parseString(s): 244 return Node(Node_parseString(s)) 245 246 def parseURI(uri): 247 return Node(Node_parseURI(uri)) 248 249 def toString(node, encoding=None): 250 return Node_toString(node.as_native_node(), encoding) 251 252 def toStream(node, stream, encoding=None): 253 Node_toStream(node.as_native_node(), stream, encoding) 254 255 def toFile(node, f, encoding=None): 256 Node_toFile(node.as_native_node(), f, encoding) 257 258 # vim: tabstop=4 expandtab shiftwidth=4