# HG changeset patch # User paulb # Date 1105838201 0 # Node ID 54e3434f30a36a1e2e04ebea95f12de406b24b99 # Parent 86d588cf616cda8596481fb880a9f5b4c59afbba [project @ 2005-01-16 01:16:30 by paulb] Moved macrolib into its own package - this library is "merged" with the importNode implementation which is actually written in traditional DOM code. diff -r 86d588cf616c -r 54e3434f30a3 libxml2dom/macrolib.py --- a/libxml2dom/macrolib.py Sun Jan 16 01:15:37 2005 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,116 +0,0 @@ -#!/usr/bin/env python - -""" -DOM macros for libxml2. -""" - -__version__ = "0.1.2" - -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 - -_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 Node_nodeType(node): - global _nodesTypes - return _nodeTypes[node.type] - -def Node_childNodes(node): - - # NOTE: Consider a generator instead. - - child_nodes = [] - node = node.children - while node is not None: - child_nodes.append(node) - node = node.next - return child_nodes - -def _getNs(node): - - "Internal namespace information retrieval." - - try: - return node.ns() - except libxml2.treeError: - return None - -def Node_namespaceURI(node): - ns = _getNs(node) - if ns is not None: - return to_unicode(ns.content) - else: - return None - -def Node_nodeValue(node): - return to_unicode(node.content) - -def Node_prefix(node): - ns = _getNs(node) - if ns is not None: - return to_unicode(ns.name) - else: - return None - -def Node_nodeName(node): - prefix = Node_prefix(node) - if prefix is not None: - return prefix + ":" + Node_localName(node) - else: - return Node_localName(node) - -def Node_tagName(node): - if node.type == "element": - return Node_nodeName(node) - else: - return None - -def Node_localName(node): - return to_unicode(node.name) - -def Node_parentNode(node): - if node.type == "document_xml": - return None - else: - return node.parent - -def Node_previousSibling(node): - if node.prev is not None: - return node.prev - else: - return None - -def Node_nextSibling(node): - if node.next is not None: - return node.next - else: - return None - -# vim: tabstop=4 expandtab shiftwidth=4 diff -r 86d588cf616c -r 54e3434f30a3 libxml2dom/macrolib/__init__.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libxml2dom/macrolib/__init__.py Sun Jan 16 01:16:41 2005 +0000 @@ -0,0 +1,13 @@ +#!/usr/bin/env python + +"libxml2dom macro library." + +# Expose all functions here. + +from libxml2dom.macrolib.macrolib import * + +# The following module must be processed by libxml2macro before use. + +from libxml2dom.macrolib.importnode import Node_importNode + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r 86d588cf616c -r 54e3434f30a3 libxml2dom/macrolib/importnode.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libxml2dom/macrolib/importnode.py Sun Jan 16 01:16:41 2005 +0000 @@ -0,0 +1,40 @@ +#!/usr/bin/env python + +""" +An import node implementation taken from libxml2dom.Node for use with libxml2macro. +""" + +from libxml2dom.macrolib.macrolib import * +import xml.dom + +def importNode(x2_self, x2_node, deep): + + if x2_node.nodeType == xml.dom.Node.ELEMENT_NODE: + x2_imported_element = x2_self.ownerDocument.createElementNS(x2_node.namespaceURI, x2_node.tagName) + for x2_value in x2_node.attributes.values(): + x2_imported_element.setAttributeNS(x2_value.namespaceURI, x2_value.nodeName, x2_value.nodeValue) + + if deep: + for child in x2_node.childNodes: + x2_imported_child = x2_self.importNode(child, deep) + if x2_imported_child: + x2_imported_element.appendChild(x2_imported_child) + + return x2_imported_element + + elif x2_node.nodeType == xml.dom.Node.TEXT_NODE: + return x2_self.ownerDocument.createTextNode(x2_node.nodeValue) + + elif x2_node.nodeType == xml.dom.Node.ATTRIBUTE_NODE: + return x2_self.ownerDocument.createAttributeNS(x2_node.namespaceURI, x2_node.name) + + elif x2_node.nodeType == xml.dom.Node.COMMENT_NODE: + return x2_self.ownerDocument.createComment(x2_node.data) + + raise ValueError, x2_node.nodeType + +# Special hack for the generated code. + +Node_importNode = importNode + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r 86d588cf616c -r 54e3434f30a3 libxml2dom/macrolib/macrolib.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libxml2dom/macrolib/macrolib.py Sun Jan 16 01:16:41 2005 +0000 @@ -0,0 +1,325 @@ +#!/usr/bin/env python + +""" +DOM macros for libxml2. +""" + +__version__ = "0.1.2" + +import xml.dom +import libxml2 +import sys + +class TemporaryNode: + def __init__(self, ns, name): + self._ns = ns + self.name = name + self.type = "attribute" + + def ns(self): + return self._ns + +# 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 + +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 + +_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 Node_ownerDocument(node): + return node.doc + +def Node_nodeType(node): + global _nodesTypes + return _nodeTypes[node.type] + +def Node_childNodes(node): + + # NOTE: Consider a generator instead. + + child_nodes = [] + node = node.children + while node is not None: + child_nodes.append(node) + node = node.next + return child_nodes + +def Node_attributes(node): + attributes = {} + node = node.properties + while node is not None: + ns = _getNs(node) + if ns is not None: + attributes[(ns.content, node.name)] = node + else: + attributes[(None, node.name)] = node + node = node.next + return attributes + +def _getNs(node): + + "Internal namespace information retrieval." + + try: + return node.ns() + except libxml2.treeError: + return None + +def Node_namespaceURI(node): + ns = _getNs(node) + if ns is not None: + return to_unicode(ns.content) + else: + return None + +def Node_nodeValue(node): + return to_unicode(node.content) + +def Node_prefix(node): + ns = _getNs(node) + if ns is not None: + return to_unicode(ns.name) + else: + return None + +def Node_nodeName(node): + prefix = Node_prefix(node) + if prefix is not None: + return prefix + ":" + Node_localName(node) + else: + return Node_localName(node) + +def Node_tagName(node): + if node.type == "element": + return Node_nodeName(node) + else: + return None + +def Node_localName(node): + return to_unicode(node.name) + +def Node_parentNode(node): + if node.type == "document_xml": + return None + else: + return node.parent + +def Node_previousSibling(node): + if node.prev is not None: + return node.prev + else: + return None + +def Node_nextSibling(node): + if node.next is not None: + return node.next + else: + return None + +def Node_hasAttributeNS(node, ns, localName): + return Node_getAttributeNS(ns, localName) is not None + +def Node_hasAttribute(node, name): + return Node_getAttribute(name) is not None + +def Node_getAttributeNS(node, ns, localName): + return to_unicode(node.nsProp(localName, ns)) + +def Node_getAttribute(node, name): + return to_unicode(node.prop(name)) + +def Node_getAttributeNodeNS(node, ns, localName): + return node.nsProp(localName, ns) + +def Node_getAttributeNode(node, name): + # NOTE: Needs verifying. + return node.prop(name) + +def Node_setAttributeNS(node, 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: + node.setNsProp(node.newNs(ns, prefix), localName, value) + elif ns is not None and ns == node.ns().content: + node.setNsProp(node.ns(), localName, value) + else: + # NOTE: Needs verifying: what should happen to the namespace? + # NOTE: This also catches the case where None is the element's + # NOTE: namespace and is also used for the attribute. + node.setNsProp(None, localName, value) + +def Node_setAttribute(node, name, value): + # NOTE: Need to convert from Unicode. + name, value = map(from_unicode, [name, value]) + + node.setProp(name, value) + +def Node_setAttributeNodeNS(node, ns, name, attr): + # NOTE: Not actually putting the node on the element. + Node_setAttributeNS(node, ns, name, Node_nodeValue(attr)) + +def Node_setAttributeNode(node, name, attr): + # NOTE: Not actually putting the node on the element. + Node_setAttribute(node, name, Node_nodeValue(attr)) + +def Node_createElementNS(node, ns, name): + # NOTE: Need to convert from Unicode. + ns, name = map(from_unicode, [ns, name]) + + prefix, localName = _get_prefix_and_localName(name) + new_node = libxml2.newNode(localName) + # NOTE: Does it make sense to set the namespace if it is empty? + if ns is not None: + new_ns = new_node.newNs(ns, prefix) + new_node.setNs(new_ns) + return new_node + +def Node_createElement(node, name): + # NOTE: Need to convert from Unicode. + name = from_unicode(name) + + new_node = libxml2.newNode(name) + return new_node + +def Node_createAttributeNS(node, ns, name): + # NOTE: Need to convert from Unicode. + ns, name = map(from_unicode, [ns, name]) + + prefix, localName = _get_prefix_and_localName(name) + # NOTE: Does it make sense to set the namespace if it is empty? + if ns is not None: + new_ns = new_node.newNs(ns, prefix) + else: + new_ns = None + return TemporaryNode(new_ns, localName) + +def Node_createAttribute(node, name): + # NOTE: Need to convert from Unicode. + name = from_unicode(name) + + return TemporaryNode(None, name) + +def Node_createTextNode(node, value): + # NOTE: Need to convert from Unicode. + value = from_unicode(value) + + return libxml2.newText(value) + +def Node_createComment(node, value): + # NOTE: Need to convert from Unicode. + value = from_unicode(value) + + return libxml2.newComment(value) + +def _add_node(node, tmp): + if tmp.ns is not None: + child = node.newNsProp(None, Node_localName(tmp), None) + ns = child.newNs(Node_namespaceURI(tmp), Node_prefix(tmp)) + child.setNs(ns) + else: + child = node.newProp(None, tmp.name, None) + + return child + +def Node_insertBefore(node, tmp, oldNode): + if isinstance(tmp, TemporaryNode): + child = _add_node(tmp) + else: + child = tmp + return oldNode.addPrevSibling(child) + +def Node_replaceChild(node, tmp, oldNode): + if isinstance(tmp, TemporaryNode): + child = _add_node(tmp) + else: + child = tmp + return oldNode.replaceNode(child) + +def Node_appendChild(node, tmp): + return node.addChild(tmp) + +def Node_removeChild(node, child): + child.unlinkNode() + +def Node_xpath(node, expr, variables=None, namespaces=None): + context = Node_ownerDocument(node).xpathNewContext() + context.setContextNode(node) + # NOTE: Discover namespaces from the node. + for prefix, ns in (namespaces or {}).items(): + context.xpathRegisterNs(prefix, ns) + # NOTE: May need to tidy up the context. + return context.xpathEval(expr) + +# Utility functions. + +def createDocumentType(localName, publicId, systemId): + return None + +def createDocument(namespaceURI, localName, doctype): + # NOTE: Fixed to use version 1.0 only. + d = libxml2.newDoc("1.0") + if localName is not None: + root = Node_createElementNS(d, namespaceURI, localName) + Node_appendChild(d, root) + return d + +def parse(stream_or_string): + if hasattr(stream_or_string, "read"): + stream = stream_or_string + return parseString(stream.read()) + else: + return parseFile(stream_or_string) + +def parseFile(s): + # NOTE: Switching off validation and remote DTD resolution. + context = libxml2.createFileParserCtxt(s) + context.validate(0) + context.ctxtUseOptions(0) + context.parseDocument() + return context.doc() + +def parseString(s): + # NOTE: Switching off validation and remote DTD resolution. + context = libxml2.createMemoryParserCtxt(s, len(s)) + context.validate(0) + context.ctxtUseOptions(0) + context.parseDocument() + return context.doc() + +def parseURI(uri): + return libxml2.parseURI(uri) + +# vim: tabstop=4 expandtab shiftwidth=4