Logo Search packages:      
Sourcecode: python-xml version File versions  Download package

javadom.py

00001 """An adapter for Java DOM implementations that makes it possible to
access them through the same interface as the Python DOM implementations.

Supports:
- Sun's Java Project X
- Xerces
- David Brownell's SAX 2.0 Utilities / DOM2
- Indelv DOM
- SXP
- OpenXML

$Id: javadom.py,v 1.7 2001/02/19 15:21:50 fdrake Exp $
"""

# Todo:
# - extend test suite
# - start using _set_up_attributes, or give up as too slow?
# - support level 2

import string

# --- Supported Java DOM implementations

00024 class BaseDomImplementation:
    """An abstract DomImplementation with some reusable implementations
    of build* methods that depend on a lower-level _parse_from_source
    method."""

    def buildDocumentString(self, string):
        from java.io import StringReader
        from org.xml.sax import InputSource
        return self._parse_from_source(InputSource(StringReader(string)))

    def buildDocumentUrl(self, url):
        return self._parse_from_source(url)

    def buildDocumentFile(self, filename):
        return self.buildDocumentUrl(filetourl(filename))

class SunDomImplementation:

    def createDocument(self):
        from com.sun.xml.tree import XmlDocument
        return Document(XmlDocument())

    def buildDocumentString(self, string):
        from com.sun.xml.tree import XmlDocumentBuilder
        return Document(XmlDocumentBuilder.createXmlDocument(string))

    def buildDocumentUrl(self, url):
        from com.sun.xml.tree import XmlDocument
        return Document(XmlDocument.createXmlDocument(url))

    def buildDocumentFile(self, filename):
        return self.buildDocumentUrl(filetourl(filename))

class XercesDomImplementation(BaseDomImplementation):

    def createDocument(self):
        from org.apache.xerces.dom import DocumentImpl
        return Document(DocumentImpl())

    def _parse_from_source(self, source):
        from org.apache.xerces.parsers import DOMParser
        p = DOMParser()
        p.parse(source)
        return Document(p.getDocument())

class BrownellDomImplementation(BaseDomImplementation):

    def createDocument(self):
        from org.brownell.xml.dom import DomDocument
        return Document(DomDocument())

    def _parse_from_source(self, source):
        from org.brownell.xml import DomBuilder
        return Document(DomBuilder.createDocument(source))

class IndelvDomImplementation(BaseDomImplementation):

    def createDocument(self):
        from com.indelv.dom import DOMImpl
        return Document(DOMImpl.createNewDocument())

    def _parse_from_source(self, source):
        from com.indelv.dom.util import XMLReader
        from org.xml.sax import InputSource
        return Document(XMLReader.parseDocument(InputSource(source)))

class SxpDomImplementation(BaseDomImplementation):

    def createDocument(self):
        from fr.loria.xml import DOMFactory
        return Document(DOMFactory().createDocument())

    def _parse_from_source(self, source):
        from fr.loria.xml import DocumentLoader
        loader = DocumentLoader()

        if type(source) == type(""):
            doc = loader.loadDocument(source)
        elif source.getCharacterStream() != None:
            doc = loader.loadDocument(source.getCharacterStream())
        elif source.getByteStream() != None:
            doc = loader.loadDocument(source.getByteStream())
        elif source.getSystemId() != None:
            doc = loader.loadDocument(source.getSystemId())

        return Document(doc)

class OpenXmlDomImplementation(BaseDomImplementation):

    def createDocument(self):
        from org.openxml.dom import DocumentImpl
        return Document(DocumentImpl())

    def _parse_from_source(self, source):
        from org.openxml.dom import SAXBuilder
        from org.openxml.parser import XMLSAXParser

        builder = SAXBuilder()
        parser = XMLSAXParser()
        parser.setDocumentHandler(builder)
        parser.parse(source)
        return Document(builder.getDocument())

# ===== Utilities

def filetourl(file):
    # A Python port of James Clark's fileToURL from XMLTest.java.
    from java.io import File
    from java.net import URL
    from java.lang import System

    file = File(file).getAbsolutePath()
    sep = System.getProperty("file.separator")

    if sep != None and len(sep) == 1:
        file = file.replace(sep[0], '/')

    if len(file) > 0 and file[0] != '/':
        file = '/' + file

    return URL('file', None, file).toString()

def _wrap_node(node):
    if node == None:
        return None

    return NODE_CLASS_MAP[node.getNodeType()] (node)

# ===== Constants

ELEMENT_NODE                = 1
ATTRIBUTE_NODE              = 2
TEXT_NODE                   = 3
CDATA_SECTION_NODE          = 4
ENTITY_REFERENCE_NODE       = 5
ENTITY_NODE                 = 6
PROCESSING_INSTRUCTION_NODE = 7
COMMENT_NODE                = 8
DOCUMENT_NODE               = 9
DOCUMENT_TYPE_NODE          = 10
DOCUMENT_FRAGMENT_NODE      = 11
NOTATION_NODE               = 12

# ===== DOMException

try:
    from org.w3c.dom import DOMException
except ImportError, e:
    pass

# ===== DOMImplementation

class DOMImplementation:

    def __init__(self, impl):
        self._impl = impl

    def hasFeature(self, feature, version):
        if version == None or version == "1.0":
            return string.lower(feature) == "xml" and \
                   self._impl.hasFeature(feature, version)
        else:
            return 0

    def __repr__(self):
        return "<DOMImplementation javadom.py, using '%s'>" % self._impl

# ===== Node

class Node:

    def __init__(self, impl):
        self.__dict__['_impl'] = impl

    # attributes

    def _get_nodeName(self):
        return self._impl.getNodeName()

    def _get_nodeValue(self):
        return self._impl.getNodeValue()

    def _get_nodeType(self):
        return self._impl.getNodeType()

    def _get_parentNode(self):
        return _wrap_node(self._impl.getParentNode())

    def _get_childNodes(self):
        children = self._impl.getChildNodes()
        if children is None:
            return children
        else:
            return NodeList(children)

    def _get_firstChild(self):
        return _wrap_node(self._impl.getFirstChild())

    def _get_lastChild(self):
        return _wrap_node(self._impl.getLastChild())

    def _get_previousSibling(self):
        return _wrap_node(self._impl.getPreviousSibling())

    def _get_nextSibling(self):
        return _wrap_node(self._impl.getNextSibling())

    def _get_ownerDocument(self):
        return _wrap_node(self._impl.getOwnerDocument())

    def _get_attributes(self):
        atts = self._impl.getAttributes()
        if atts is None:
            return None
        else:
            return NamedNodeMap(atts)

    # methods

    def insertBefore(self, new, neighbour):
        self._impl.insertBefore(new._impl, neighbour._impl)

    def replaceChild(self, new, old):
        self._impl.replaceChild(new._impl, old._impl)
        return old

    def removeChild(self, old):
        self._impl.removeChild(old._impl)
        return old

    def appendChild(self, new):
        return self._impl.appendChild(new._impl)

    def hasChildNodes(self):
        return self._impl.hasChildNodes()

    def cloneNode(self):
        return _wrap_node(self._impl.cloneNode())

    # python

    def __getattr__(self, name):
        if name[ : 5] != '_get_':
            return getattr(self, '_get_' + name) ()

        raise AttributeError, name

    def __setattr__(self, name, value):
        getattr(self, '_set_' + name) (value)

# ===== Document

class Document(Node):

    def __init__(self, impl):
        Node.__init__(self, impl)

    # methods

    def createTextNode(self, data):
        return Text(self._impl.createTextNode(data))

    def createEntityReference(self, name):
        return EntityReference(self._impl.createEntityReference(name))

    def createElement(self, name):
        return Element(self._impl.createElement(name))

    def createDocumentFragment(self):
        return DocumentFragment(self._impl.createDocumentFragment())

    def createComment(self, data):
        return Comment(self._impl.createComment(data))

    def createCDATASection(self, data):
        return CDATASection(self._impl.createCDATASection(data))

    def createProcessingInstruction(self, target, data):
        return ProcessingInstruction(self._impl.createProcessingInstruction(target, data))

    def createAttribute(self, name):
        return Attr(self._impl.createAttribute(name))

    def getElementsByTagName(self, name):
        return NodeList(self._impl.getElementsByTagName(name))

    # attributes

    def _get_doctype(self):
        return self._impl.getDoctype()

    def _get_implementation(self):
        return DOMImplementation(self._impl.getImplementation())

    def _get_documentElement(self):
        return _wrap_node(self._impl.getDocumentElement())

    # python

    def __repr__(self):
        docelm = self._impl.getDocumentElement()
        if docelm:
            return "<Document with root '%s'>" % docelm.getTagName()
        else:
            return "<Document with no root>"

# ===== Element

class Element(Node):

    def __init__(self, impl):
        Node.__init__(self, impl)

        self.__dict__['_get_tagName']    = self._impl.getTagName
        self.__dict__['getAttribute']    = self._impl.getAttribute
        self.__dict__['setAttribute']    = self._impl.setAttribute
        self.__dict__['removeAttribute'] = self._impl.removeAttribute
        self.__dict__['normalize']       = self._impl.normalize

    # methods

    def getAttributeNode(self, name):
        node = self._impl.getAttributeNode(name)
        if node == None:
            return node
        else:
            return Attr(node)

    def setAttributeNode(self, attr):
        self._impl.setAttributeNode(attr._impl)

    def removeAttributeNode(self, attr):
        self._impl.removeAttributeNode(attr._impl)

    def getElementsByTagName(self, name):
        return NodeList(self._impl.getElementsByTagName(name))

    # python

    def __repr__(self):
        return "<Element '%s' with %d attributes and %d children>" % \
               (self._impl.getTagName(),
                self._impl.getAttributes().getLength(),
                self._impl.getChildNodes().getLength())

# ===== CharacterData

class CharacterData(Node):

    def __init__(self, impl):
        Node.__init__(self, impl)

        self.__dict__['_get_data']     = self._impl.getData
        self.__dict__['_set_data']     = self._impl.setData
        self.__dict__['_get_length']   = self._impl.getLength

        self.__dict__['substringData'] = self._impl.substringData
        self.__dict__['appendData']    = self._impl.appendData
        self.__dict__['insertData']    = self._impl.insertData
        self.__dict__['deleteData']    = self._impl.deleteData
        self.__dict__['replaceData']   = self._impl.replaceData

# ===== Comment

class Comment(CharacterData):

    def __repr__(self):
        return "<Comment of length %d>" % self.getLength()

# ===== ProcessingInstruction

class ProcessingInstruction(Node):

    def __init__(self, impl):
        Node.__init__(self, impl)

        self.__dict__['_get_target'] = self._impl.getTarget
        self.__dict__['_get_data']   = self._impl.getData
        self.__dict__['_set_data']   = self._impl.setData

    def __repr__(self):
        return "<PI with target '%s'>" % self._impl.getTarget()

# ===== Text

class Text(CharacterData):

    def splitText(self, offset):
        return Text(self._impl.splitText(offset))

    def __repr__(self):
        return "<Text of length %d>" % self._impl.getLength()

# ===== CDATASection

class CDATASection(Text):

    def __repr__(self):
        return "<CDATA section of length %d>" % self._impl.getLength()

# ===== Attr

class Attr(Node):

    def __init__(self, impl):
        Node.__init__(self, impl)

        self.__dict__['_get_name']      = self._impl.getName
        self.__dict__['_get_specified'] = self._impl.getSpecified
        self.__dict__['_get_value']     = self._impl.getValue
        self.__dict__['_set_value']     = self._impl.setValue

    def __repr__(self):
        return "<Attr '%s'>" % self._impl.getName()

# ===== EntityReference

class EntityReference(Node):

    def __repr__(self):
        return "<EntityReference '%s'>" % self.getNodeName()

# ===== DocumentType

class DocumentType(Node):

    def __init__(self, impl):
        Node.__init__(self, impl)

        self.__dict__['_get_name'] = self._impl.getName

    def _get_entities(self):
        return NamedNodeMap(self._impl.getEntities())

    def _get_notations(self):
        return NamedNodeMap(self._impl.getNotations())

    def __repr__(self):
        return "<DocumentType '%s'>" % self._impl.getNodeName()

# ===== Notation

class Notation(Node):

    def __init__(self, impl):
        Node.__init__(self, impl)

        self.__dict__['_get_publicId'] = self._impl.getPublicId
        self.__dict__['_get_systemId'] = self._impl.getSystemId

    def __repr__(self):
        return "<Notation '%s'>" % self._impl.getNodeName()

# ===== Entity

class Entity(Node):

    def __init__(self, impl):
        Node.__init__(self, impl)

        self.__dict__['_get_publicId']     = self._impl.getPublicId
        self.__dict__['_get_systemId']     = self._impl.getSystemId
        self.__dict__['_get_notationName'] = self._impl.getNotationName

    def __repr__(self):
        return "<Entity '%s'>" % self._impl.getNodeName()

# ===== DocumentFragment

class DocumentFragment(Node):

    def __repr__(self):
        return "<DocumentFragment>"

# ===== NodeList

class NodeList:

    def __init__(self, impl):
        self._impl = impl

        self.__dict__['__len__']     = self._impl.getLength
        self.__dict__['_get_length'] = self._impl.getLength
        self.__dict__['item']        = self._impl.item

    # Python list methods

    def __getitem__(self, ix):
        if ix < 0:
            ix = len(self) + ix

        node = self._impl.item(ix)
        if node == None:
            raise IndexError, ix
        else:
            return _wrap_node(node)

    def __setitem__(self, ix, item):
        raise TypeError, "NodeList instances don't support item assignment"

    def __delitem__(self, ix, item):
        raise TypeError, "NodeList instances don't support item deletion"

    def __setslice__(self, i, j, list):
        raise TypeError, "NodeList instances don't support slice assignment"

    def __delslice__(self, i, j):
        raise TypeError, "NodeList instances don't support slice deletion"

    def append(self, item):
        raise TypeError, "NodeList instances don't support .append()"

    def insert(self, i, item):
        raise TypeError, "NodeList instances don't support .insert()"

    def pop(self, i=-1):
        raise TypeError, "NodeList instances don't support .pop()"

    def remove(self, item):
        raise TypeError, "NodeList instances don't support .remove()"

    def reverse(self):
        raise TypeError, "NodeList instances don't support .reverse()"

    def sort(self, *args):
        raise TypeError, "NodeList instances don't support .sort()"

    def __add__(self, *args):
        raise TypeError, "NodeList instances don't support +"

    def __radd__(self, *args):
        raise TypeError, "NodeList instances don't support +"

    def __mul__(self, *args):
        raise TypeError, "NodeList instances don't support *"

    def __rmul__(self, *args):
        raise TypeError, "NodeList instances don't support *"

    def count(self, *args):
        raise TypeError, "NodeList instances can't support count without equality"

    def count(self, *args):
        raise TypeError, "NodeList instances can't support index without equality"

    def __getslice__(self, i, j):
        if i < len(self):
            i = len(self) + i
        if j < len(self):
            j = len(self) + j

        slice = []
        for ix in range(i, min(j, len(self))):
            slice.append(self[ix])
        return slice

    def __repr__(self):
        return "<NodeList [ %s ]>" % string.join(map(repr, self), ", ")

# ===== NamedNodeMap

class NamedNodeMap:

    def __init__(self, impl):
        self._impl = impl

        self.__dict__['_get_length'] = self._impl.getLength
        self.__dict__['__len__']     = self._impl.getLength

    # methods

    def getNamedItem(self, name):
        return _wrap_node(self._impl.getNamedItem(name))

    def setNamedItem(self, node):
        return _wrap_node(self._impl.setNamedItem(node._impl))

    def removeNamedItem(self, name):
        return _wrap_node(self._impl.removeNamedItem(name))

    def item(self, index):
        return _wrap_node(self._impl.item(index))

    # Python dictionary methods

    def __getitem__(self, key):
        node = self._impl.getNamedItem(key)

        if node is None:
            raise KeyError, key
        else:
            return _wrap_node(node)

    def get(self, key, alternative = None):
        node = self._impl.getNamedItem(key)
        if node is None:
            return alternative
        else:
            return _wrap_node(node)

    def has_key(self, key):
        return self._impl.getNamedItem(key) != None

    def items(self):
        list = []
        for ix in range(self._impl.getLength()):
            node = self._impl.item(ix)
            list.append((node.getNodeName(), _wrap_node(node)))
        return list

    def keys(self):
        list = []
        for ix in range(self._impl.getLength()):
            list.append(self._impl.item(ix)._get_nodeName())
        return list

    def values(self):
        list = []
        for ix in range(self._impl.getLength()):
            list.append(_wrap_node(self._impl.item(ix)))
        return list

    def __setitem__(self, key, item):
        assert key == item._impl._get_nodeName()
        self._impl.setNamedItem(item._impl)

    def update(self, nnm):
        for v in nnm.values():
            self._impl.setNamedItem(v._impl)

    def __repr__(self):
        pairs = []
        for pair in self.items():
            pairs.append("'%s' : %s" % pair)
        return "<NamedNodeMap { %s }>" % string.join(pairs, ", ")

# ===== Various stuff

NODE_CLASS_MAP = {
    ELEMENT_NODE : Element,
    ATTRIBUTE_NODE : Attr,
    TEXT_NODE : Text,
    CDATA_SECTION_NODE : CDATASection,
    ENTITY_REFERENCE_NODE : EntityReference,
    ENTITY_NODE : Entity,
    PROCESSING_INSTRUCTION_NODE : ProcessingInstruction,
    COMMENT_NODE : Comment,
    DOCUMENT_NODE : Document,
    DOCUMENT_TYPE_NODE : DocumentType,
    DOCUMENT_FRAGMENT_NODE : DocumentFragment,
    NOTATION_NODE : Notation
    }

# ===== Self-test

if __name__ == "__main__":
    impl = BrownellDomImplementation() #XercesDomImplementation()  #SunDomImplementation()
    doc2 = impl.createDocument()
    print doc2
    print doc2._get_implementation()
    root = doc2.createElement("doc")
    print root
    doc2.appendChild(root)
    txt = doc2.createTextNode("This is a simple sample \n")
    print txt
    root.appendChild(txt)

    print root._get_childNodes()[0]
    print root._get_childNodes()

    root.setAttribute("huba", "haba")
    print root
    print root._get_attributes()

Generated by  Doxygen 1.6.0   Back to index