# HG changeset patch # User paulb # Date 1074377284 0 # Node ID c6fb94bab7245f56a290a5fdb33211953922bb9d # Parent 53d341a824e2e16ef8584e033eda15369d4dee52 [project @ 2004-01-17 22:08:04 by paulb] Moved package contents into a subdirectory. diff -r 53d341a824e2 -r c6fb94bab724 __init__.py --- a/__init__.py Sat Nov 15 00:15:25 2003 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,396 +0,0 @@ -#!/usr/bin/env python - -""" -DOM wrapper around libxml2. -""" - -import xml.dom -import libxml2 -import sys - -# NOTE: libxml2 seems to use UTF-8 throughout. - -def from_unicode(s): - if type(s) == type(u""): - return s.encode("utf-8") - else: - return s - -def to_unicode(s): - if type(s) == type(""): - return unicode(s, encoding="utf-8") - else: - return s - -# NOTE: Consider a generator instead. - -class NamedNodeMap(object): - - def __init__(self, node): - self.node = node - - def getNamedItem(self, name): - return self.node.getAttributeNode(name) - - def getNamedItemNS(self, ns, localName): - return self.node.getAttributeNodeNS(ns, localName) - - def setNamedItem(self, node): - self.node.setAttributeNode(node.name, node) - - def setNamedItemNS(self, node): - self.node.setAttributeNodeNS(node.namespaceURI, node.localName, node) - - def __getitem__(self, name): - return self.getNamedItem(name) - - def __setitem__(self, name, node): - if name == node.nodeName: - self.setNamedItem(node) - else: - raise KeyError, name - - def __delitem__(self, name): - # NOTE: To be implemented. - pass - - def values(self): - attributes = [] - _attribute = self.node.as_native_node().properties - while _attribute is not None: - attributes.append(Node(_attribute, ownerElement=self.node)) - _attribute = _attribute.next - return attributes - - def keys(self): - return [(attr.namespaceURI, attr.localName) for attr in self.values()] - - def items(self): - return [((attr.namespaceURI, attr.localName), attr) for attr in self.values()] - - def __repr__(self): - return str(self) - - def __str__(self): - return "{%s}" % ",\n".join(["%s : %s" % (repr(key), repr(value)) for key, value in self.items()]) - -def _get_prefix_and_localName(name): - t = name.split(":") - if len(t) == 1: - return None, name - elif len(t) == 2: - return t - else: - # NOTE: Should raise an exception. - return None, None - -class TemporaryNode(object): - def __init__(self, ns, name, nodeType): - self.ns = ns - self.name = name - self.nodeType = nodeType - self.prefix, self.localName = _get_prefix_and_localName(self.name) - -class Node(object): - - _nodeTypes = { - "attribute" : xml.dom.Node.ATTRIBUTE_NODE, - "comment" : xml.dom.Node.COMMENT_NODE, - "document_xml" : xml.dom.Node.DOCUMENT_NODE, - "doctype" : xml.dom.Node.DOCUMENT_TYPE_NODE, - "dtd" : xml.dom.Node.DOCUMENT_TYPE_NODE, # NOTE: Needs verifying. - "element" : xml.dom.Node.ELEMENT_NODE, - "entity" : xml.dom.Node.ENTITY_NODE, - "entity_ref" : xml.dom.Node.ENTITY_REFERENCE_NODE, - "notation" : xml.dom.Node.NOTATION_NODE, - "pi" : xml.dom.Node.PROCESSING_INSTRUCTION_NODE, - "text" : xml.dom.Node.TEXT_NODE - } - - def __init__(self, node, ownerElement=None, doctype=None): - self._node = node - self.ownerElement = ownerElement - self.doctype = doctype - - def as_native_node(self): - return self._node - - def _ownerDocument(self): - return Node(self._node.doc) - - def _nodeType(self): - return self._nodeTypes[self._node.type] - - def _childNodes(self): - - # NOTE: Consider a generator instead. - - child_nodes = [] - _node = self._node.children - while _node is not None: - child_nodes.append(Node(_node)) - _node = _node.next - return child_nodes - - def _attributes(self): - return NamedNodeMap(self) - - def _getNs(self): - - "Internal namespace information retrieval." - - try: - return self._node.ns() - except libxml2.treeError: - return None - - def _namespaceURI(self): - ns = self._getNs() - if ns is not None: - return to_unicode(ns.content) - else: - return None - - def _nodeValue(self): - return to_unicode(self._node.content) - - def _prefix(self): - ns = self._getNs() - if ns is not None: - return to_unicode(ns.name) - else: - return None - - def _nodeName(self): - prefix = self._prefix() - if prefix is not None: - return prefix + ":" + self._localName() - else: - return self._localName() - - def _tagName(self): - if self._node.type == "element": - return self._nodeName() - else: - return None - - def _localName(self): - return to_unicode(self._node.name) - - def _parentNode(self): - if self.nodeType == xml.dom.Node.DOCUMENT_NODE: - return None - else: - return Node(self._node.parent) - - def _nextSibling(self): - if self._node.next is not None: - return Node(self._node.next) - else: - return None - - def hasAttributeNS(self, ns, localName): - return self.getAttributeNS(ns, localName) is not None - - def hasAttribute(self, name): - return self.getAttribute(name) is not None - - def getAttributeNS(self, ns, localName): - return to_unicode(self._node.nsProp(localName, ns)) - - def getAttribute(self, name): - return to_unicode(self._node.prop(name)) - - def getAttributeNodeNS(self, ns, localName): - return self.attributes[(ns, localName)] - - def getAttributeNode(self, localName): - # NOTE: Needs verifying. - return self.attributes[(None, localName)] - - def setAttributeNS(self, ns, name, value): - # NOTE: Need to convert from Unicode. - ns, name, value = map(from_unicode, [ns, name, value]) - - prefix, localName = _get_prefix_and_localName(name) - if prefix is not None: - self._node.setNsProp(self._node.newNs(ns, prefix), localName, value) - elif ns == self._node.ns().content: - self._node.setNsProp(self._node.ns().content, localName, value) - else: - # NOTE: Needs verifying: what should happen to the namespace? - self._node.setNsProp(None, localName, value) - - def setAttribute(self, name, value): - # NOTE: Need to convert from Unicode. - name, value = map(from_unicode, [name, value]) - - self._node.setProp(name, value) - - def setAttributeNodeNS(self, ns, name, node): - # NOTE: Not actually putting the node on the element. - self.setAttributeNS(ns, name, node.nodeValue) - - def setAttributeNode(self, name, node): - # NOTE: Not actually putting the node on the element. - self.setAttribute(name, node.nodeValue) - - def createElementNS(self, ns, name): - # NOTE: Need to convert from Unicode. - ns, name = map(from_unicode, [ns, name]) - - prefix, localName = _get_prefix_and_localName(name) - _node = libxml2.newNode(localName) - _ns = _node.newNs(ns, prefix) - _node.setNs(_ns) - return Node(_node) - - def createElement(self, name): - # NOTE: Need to convert from Unicode. - name = from_unicode(name) - - _node = libxml2.newNode(localName) - return Node(_node) - - def createAttributeNS(self, ns, name): - # NOTE: Need to convert from Unicode. - ns, name = map(from_unicode, [ns, name]) - - prefix, localName = _get_prefix_and_localName(name) - return TemporaryNode(ns, name, xml.dom.Node.ATTRIBUTE_NODE) - - def createAttribute(self, name): - # NOTE: Need to convert from Unicode. - name = from_unicode(name) - - return TemporaryNode(ns, name, xml.dom.Node.ATTRIBUTE_NODE) - - def createTextNode(self, value): - # NOTE: Need to convert from Unicode. - name = from_unicode(name) - - return Node(libxml2.newText(value)) - - def _add_node(self, tmp): - if tmp.nodeType == xml.dom.Node.ATTRIBUTE_NODE: - if tmp.ns is not None: - _child = self._node.newNsProp(None, tmp.localName, None) - _ns = _child.newNs(tmp.ns, tmp.prefix) - _child.setNs(_ns) - else: - _child = self._node.newProp(None, tmp.name, None) - else: - _child = None - - return _child - - def importNode(self, node, deep): - - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - imported_element = self.ownerDocument.createElementNS(node.namespaceURI, node.tagName) - for value in node.attributes.values(): - imported_element.setAttributeNS(value.namespaceURI, value.nodeName, value.nodeValue) - - if deep: - for child in node.childNodes: - imported_child = self.importNode(child, deep) - if imported_child: - imported_element.appendChild(imported_child) - - return imported_element - - elif node.nodeType == xml.dom.Node.TEXT_NODE: - return self.ownerDocument.createTextNode(node.nodeValue) - - elif node.nodeType == xml.dom.Node.ATTRIBUTE_NODE: - return self.ownerDocument.createAttributeNS(node.namespaceURI, node.name) - - raise ValueError, node.nodeType - - def insertBefore(self, tmp, oldNode): - if tmp.nodeType == xml.dom.Node.TEXT_NODE: - _child = tmp._node - elif tmp.nodeType == xml.dom.Node.ELEMENT_NODE: - _child = tmp._node - else: - _child = self._add_node(tmp) - _child.unlinkNode() - return Node(oldNode._node.addPrevSibling(_child)) - - def replaceChild(self, tmp, oldNode): - if tmp.nodeType == xml.dom.Node.TEXT_NODE: - _child = tmp._node - elif tmp.nodeType == xml.dom.Node.ELEMENT_NODE: - _child = tmp._node - else: - _child = self._add_node(tmp) - _child.unlinkNode() - return Node(oldNode._node.replaceNode(_child)) - - def appendChild(self, tmp): - if tmp.nodeType == xml.dom.Node.TEXT_NODE: - _child = self._node.addChild(tmp._node) - elif tmp.nodeType == xml.dom.Node.ELEMENT_NODE: - _child = self._node.addChild(tmp._node) - else: - _child = self._add_node(tmp) - return Node(_child) - - def removeChild(self, tmp): - tmp._node.unlinkNode() - - #doctype defined in __init__ - #ownerElement defined in __init__ - ownerDocument = property(_ownerDocument) - childNodes = property(_childNodes) - value = data = nodeValue = property(_nodeValue) - name = nodeName = property(_nodeName) - tagName = property(_tagName) - namespaceURI = property(_namespaceURI) - prefix = property(_prefix) - localName = property(_localName) - parentNode = property(_parentNode) - nodeType = property(_nodeType) - attributes = property(_attributes) - nextSibling = property(_nextSibling) - - def isSameNode(self, other): - return self._node.nodePath() == other._node.nodePath() - - def __eq__(self, other): - return self._node.nodePath() == other._node.nodePath() - -# Utility functions. - -def createDocumentType(localName, publicId, systemId): - return None - -def createDocument(namespaceURI, localName, doctype): - # NOTE: Fixed to use version 1.0 only. - d = Node(libxml2.newDoc("1.0"), doctype=doctype) - if localName is not None: - root = d.createElementNS(namespaceURI, localName) - d.appendChild(root) - return d - -def parse(stream_or_string): - if hasattr(stream_or_string, "read"): - stream = stream_or_string - else: - stream = open(stream_or_string) - return parseString(stream.read()) - -def parseString(s): - return Node(libxml2.parseDoc(s)) - -def parseURI(uri): - return Node(libxml2.parseURI(uri)) - -def toString(node): - return node.as_native_node().serialize() - -def toStream(node, stream=None): - stream = stream or sys.stdout - stream.write(toString(node)) - -# vim: tabstop=4 expandtab shiftwidth=4