# # Copyright 2003 Roman Kennke # # This file is part of Python-SOAP. # # Python-SOAP is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # Python-SOAP is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Python-SOAP; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA """Implements some functions that help DOM processing. Author: Roman Kennke Revision: $Revision: 1.2 $ """ from xml.dom import Node def lookupPrefix(node, namespaceURI): """Looks up a namespace prefix for the given namespaceURI, starting from node. This method is defined as a method of the Node interface in DOM level 3, but is included here as a convenience method, since these are not yet implemented """ if (namespaceURI is None) or (namespaceURI == ''): return None type = node.nodeType if type == Node.ELEMENT_NODE: return lookupNamespacePrefix(node, namespaceURI, node) elif type == Node.DOCUMENT_NODE: return lookupPrefix(node.documentElement, namespaceURI) elif (type == Node.ENTITY_NODE) or \ (type == Node.NOTATION_NODE) or \ (type == Node.DOCUMENT_FRAGMENT_NODE) or \ (type == Node.DOCUMENT_TYPE_NODE): return None elif (type == Node.ATTRIBUTE_NODE): if node.ownerElement is not None: return lookupNamespacePrefix(node.ownerElement, namespaceURI) return None else: if (node.parentNode is not None) and \ (node.parentNode.nodeType != Node.DOCUMENT_NODE): return lookupPrefix(node.parentNode, namespaceURI) def lookupNamespacePrefix(node, namespaceURI, element): if (node.namespaceURI is not None) and \ (node.namespaceURI == namespaceURI) and \ (node.prefix is not None) and \ (lookupNamespaceURI(element, node.prefix) == namespaceURI): return node.prefix if len(node.attributes) > 0: for attr in node.attributes: if (attr.prefix == 'xmlns') and \ (attr.value == namespaceURI) and \ (lookupNamespaceURI(element, attr.localName) == \ namespaceURI): return attr.localName if (node.parentNode is not None) and \ (node.parentNode.nodeType != Node.DOCUMENT_NODE): return lookupNamespacePrefix(node.parentNode, namespaceURI, element) return None def lookupNamespaceURI(node, prefix): """Looks up a namespace URI by its prefix in the scope of the DOM Node node. This is a method defined for DOM Node in DOM Level 3, but is not (yet) implemented in current Python DOM implementations.""" if node.nodeType == Node.ELEMENT_NODE: if (node.namespaceURI is not None) and\ (node.prefix == prefix): return node.namespaceURI if (node.attributes.length != 0): for index in range(0, node.attributes.length): attr = node.attributes.item(index) if (attr.prefix == 'xmlns') and (attr.localName == prefix): # non-default namespace if attr.nodeValue != '': return attr.nodeValue return None elif (attr.prefix == 'xmlns') and (prefix == None): # default namespace if attr.nodeValue != '': return attr.nodeValue return None # end attribute searchloop if (node.parentNode is not None) and\ (node.parentNode.nodeType != Node.DOCUMENT_NODE): return lookupNamespaceURI(node.parentNode, prefix) return None elif node.nodeType == Node.DOCUMENT_NODE: return lookupNamespaceURI(node.documentElement, prefix) elif (node.nodeType == Node.ENTITY_NODE) or\ (node.nodeType == Node.NOTATION_NODE) or\ (node.nodeType == Node.DOCUMENT_TYPE_NODE) or\ (node.nodeType == Node.DOCUMENT_FRAGMENT_NODE): return None elif node.nodeType == Node.ATTRIBUTE_NODE: raise Exception('not implementable yet') else: if node.parentNode is not None: return lookupNamespaceURI(node.parentNode, prefix) else: return None def getTextContent(domNode): """Extracts and returns all Text Node children of the given DOM Node. It is considered an error, if there are any other types of nodes, like elements within the child Nodes.""" from StringIO import StringIO buffer = StringIO() for child in domNode.childNodes: if (child.nodeType != Node.TEXT_NODE) and \ (child.nodeType != Node.CDATA_SECTION_NODE): import soapdom raise soapdom.DeserializerException\ ('unexpected child node. Expected Node type is TEXT_NODE') buffer.write(child.data) return buffer.getvalue() def getElementChildren(domNode): """Extracts and returns all Element children of the given DOM Node. It is considered an error, if there are any child nodes, other than Elements, Comments, or whitespaced Text Nodes.""" childElements = [] for child in domNode.childNodes: type = child.nodeType if type == Node.ELEMENT_NODE: childElements.append(child) elif type == Node.COMMENT_NODE: continue elif type == Node.TEXT_NODE: import string if string.strip(child.data) != '': raise soapdom.DeserializerException\ ('unexpected textual content') continue else: raise soapdom.DeserializerException\ ('unexpected content') return childElements