diff options
author | jhugunin <jhugunin> | 2003-01-03 23:19:47 +0000 |
---|---|---|
committer | jhugunin <jhugunin> | 2003-01-03 23:19:47 +0000 |
commit | 8ec8f0c0c6c68d9b13c3bc3416c3234eddd48379 (patch) | |
tree | 8a2e07ba2a0048aae570053e019e02bd093f175f /lib/jython/Lib/xml/dom/minidom.py | |
parent | f685f979a4d3eb3844f74850deece1da265bc975 (diff) | |
download | aspectj-8ec8f0c0c6c68d9b13c3bc3416c3234eddd48379.tar.gz aspectj-8ec8f0c0c6c68d9b13c3bc3416c3234eddd48379.zip |
making jython-2.1 available for scripting
Diffstat (limited to 'lib/jython/Lib/xml/dom/minidom.py')
-rw-r--r-- | lib/jython/Lib/xml/dom/minidom.py | 916 |
1 files changed, 916 insertions, 0 deletions
diff --git a/lib/jython/Lib/xml/dom/minidom.py b/lib/jython/Lib/xml/dom/minidom.py new file mode 100644 index 000000000..37649c4c2 --- /dev/null +++ b/lib/jython/Lib/xml/dom/minidom.py @@ -0,0 +1,916 @@ +"""\
+minidom.py -- a lightweight DOM implementation.
+
+parse("foo.xml")
+
+parseString("<foo><bar/></foo>")
+
+Todo:
+=====
+ * convenience methods for getting elements and text.
+ * more testing
+ * bring some of the writer and linearizer code into conformance with this
+ interface
+ * SAX 2 namespaces
+"""
+
+import string
+_string = string
+del string
+
+from xml.dom import HierarchyRequestErr
+
+# localize the types, and allow support for Unicode values if available:
+import types
+_TupleType = types.TupleType
+try:
+ _StringTypes = (types.StringType, types.UnicodeType)
+except AttributeError:
+ _StringTypes = (types.StringType,)
+del types
+
+import xml.dom
+_Node = xml.dom.Node
+
+class Node(_Node):
+ allnodes = {}
+ _debug = 0
+ _makeParentNodes = 1
+ debug = None
+ childNodeTypes = ()
+ namespaceURI = None # this is non-null only for elements and attributes
+
+ def __init__(self):
+ self.childNodes = []
+ self.parentNode = self.ownerDocument = None
+ if Node._debug:
+ index = repr(id(self)) + repr(self.__class__)
+ Node.allnodes[index] = repr(self.__dict__)
+ if Node.debug is None:
+ Node.debug = _get_StringIO()
+ #open("debug4.out", "w")
+ Node.debug.write("create %s\n" % index)
+
+ def __getattr__(self, key):
+ if key[0:2] == "__":
+ raise AttributeError, key
+ # getattr should never call getattr!
+ if self.__dict__.has_key("inGetAttr"):
+ del self.inGetAttr
+ raise AttributeError, key
+
+ prefix, attrname = key[:5], key[5:]
+ if prefix == "_get_":
+ self.inGetAttr = 1
+ if hasattr(self, attrname):
+ del self.inGetAttr
+ return (lambda self=self, attrname=attrname:
+ getattr(self, attrname))
+ else:
+ del self.inGetAttr
+ raise AttributeError, key
+ else:
+ self.inGetAttr = 1
+ try:
+ func = getattr(self, "_get_" + key)
+ except AttributeError:
+ raise AttributeError, key
+ del self.inGetAttr
+ return func()
+
+ def __nonzero__(self):
+ return 1
+
+ def toxml(self):
+ writer = _get_StringIO()
+ self.writexml(writer)
+ return writer.getvalue()
+
+ def toprettyxml(self, indent="\t", newl="\n"):
+ # indent = the indentation string to prepend, per level
+ # newl = the newline string to append
+ writer = _get_StringIO()
+ self.writexml(writer, "", indent, newl)
+ return writer.getvalue()
+
+ def hasChildNodes(self):
+ if self.childNodes:
+ return 1
+ else:
+ return 0
+
+ def _get_firstChild(self):
+ if self.childNodes:
+ return self.childNodes[0]
+
+ def _get_lastChild(self):
+ if self.childNodes:
+ return self.childNodes[-1]
+
+ def insertBefore(self, newChild, refChild):
+ if newChild.nodeType == self.DOCUMENT_FRAGMENT_NODE:
+ for c in newChild.childNodes:
+ self.insertBefore(c, refChild)
+ ### The DOM does not clearly specify what to return in this case
+ return newChild
+ if newChild.nodeType not in self.childNodeTypes:
+ raise HierarchyRequestErr, \
+ "%s cannot be child of %s" % (repr(newChild), repr(self))
+ if newChild.parentNode is not None:
+ newChild.parentNode.removeChild(newChild)
+ if refChild is None:
+ self.appendChild(newChild)
+ else:
+ index = self.childNodes.index(refChild)
+ self.childNodes.insert(index, newChild)
+ newChild.nextSibling = refChild
+ refChild.previousSibling = newChild
+ if index:
+ node = self.childNodes[index-1]
+ node.nextSibling = newChild
+ newChild.previousSibling = node
+ else:
+ newChild.previousSibling = None
+ if self._makeParentNodes:
+ newChild.parentNode = self
+ return newChild
+
+ def appendChild(self, node):
+ if node.nodeType == self.DOCUMENT_FRAGMENT_NODE:
+ for c in node.childNodes:
+ self.appendChild(c)
+ ### The DOM does not clearly specify what to return in this case
+ return node
+ if node.nodeType not in self.childNodeTypes:
+ raise HierarchyRequestErr, \
+ "%s cannot be child of %s" % (repr(node), repr(self))
+ if node.parentNode is not None:
+ node.parentNode.removeChild(node)
+ if self.childNodes:
+ last = self.lastChild
+ node.previousSibling = last
+ last.nextSibling = node
+ else:
+ node.previousSibling = None
+ node.nextSibling = None
+ self.childNodes.append(node)
+ if self._makeParentNodes:
+ node.parentNode = self
+ return node
+
+ def replaceChild(self, newChild, oldChild):
+ if newChild.nodeType == self.DOCUMENT_FRAGMENT_NODE:
+ refChild = oldChild.nextSibling
+ self.removeChild(oldChild)
+ return self.insertBefore(newChild, refChild)
+ if newChild.nodeType not in self.childNodeTypes:
+ raise HierarchyRequestErr, \
+ "%s cannot be child of %s" % (repr(newChild), repr(self))
+ if newChild.parentNode is not None:
+ newChild.parentNode.removeChild(newChild)
+ if newChild is oldChild:
+ return
+ index = self.childNodes.index(oldChild)
+ self.childNodes[index] = newChild
+ if self._makeParentNodes:
+ newChild.parentNode = self
+ oldChild.parentNode = None
+ newChild.nextSibling = oldChild.nextSibling
+ newChild.previousSibling = oldChild.previousSibling
+ oldChild.nextSibling = None
+ oldChild.previousSibling = None
+ if newChild.previousSibling:
+ newChild.previousSibling.nextSibling = newChild
+ if newChild.nextSibling:
+ newChild.nextSibling.previousSibling = newChild
+ return oldChild
+
+ def removeChild(self, oldChild):
+ self.childNodes.remove(oldChild)
+ if oldChild.nextSibling is not None:
+ oldChild.nextSibling.previousSibling = oldChild.previousSibling
+ if oldChild.previousSibling is not None:
+ oldChild.previousSibling.nextSibling = oldChild.nextSibling
+ oldChild.nextSibling = oldChild.previousSibling = None
+
+ if self._makeParentNodes:
+ oldChild.parentNode = None
+ return oldChild
+
+ def normalize(self):
+ L = []
+ for child in self.childNodes:
+ if child.nodeType == Node.TEXT_NODE:
+ data = child.data
+ if data and L and L[-1].nodeType == child.nodeType:
+ # collapse text node
+ node = L[-1]
+ node.data = node.nodeValue = node.data + child.data
+ node.nextSibling = child.nextSibling
+ child.unlink()
+ elif data:
+ if L:
+ L[-1].nextSibling = child
+ child.previousSibling = L[-1]
+ else:
+ child.previousSibling = None
+ L.append(child)
+ else:
+ # empty text node; discard
+ child.unlink()
+ else:
+ if L:
+ L[-1].nextSibling = child
+ child.previousSibling = L[-1]
+ else:
+ child.previousSibling = None
+ L.append(child)
+ if child.nodeType == Node.ELEMENT_NODE:
+ child.normalize()
+ self.childNodes[:] = L
+
+ def cloneNode(self, deep):
+ import new
+ clone = new.instance(self.__class__, self.__dict__.copy())
+ if self._makeParentNodes:
+ clone.parentNode = None
+ clone.childNodes = []
+ if deep:
+ for child in self.childNodes:
+ clone.appendChild(child.cloneNode(1))
+ return clone
+
+ # DOM Level 3 (Working Draft 2001-Jan-26)
+
+ def isSameNode(self, other):
+ return self is other
+
+ # minidom-specific API:
+
+ def unlink(self):
+ self.parentNode = self.ownerDocument = None
+ for child in self.childNodes:
+ child.unlink()
+ self.childNodes = None
+ self.previousSibling = None
+ self.nextSibling = None
+ if Node._debug:
+ index = repr(id(self)) + repr(self.__class__)
+ self.debug.write("Deleting: %s\n" % index)
+ del Node.allnodes[index]
+
+def _write_data(writer, data):
+ "Writes datachars to writer."
+ replace = _string.replace
+ data = replace(data, "&", "&")
+ data = replace(data, "<", "<")
+ data = replace(data, "\"", """)
+ data = replace(data, ">", ">")
+ writer.write(data)
+
+def _getElementsByTagNameHelper(parent, name, rc):
+ for node in parent.childNodes:
+ if node.nodeType == Node.ELEMENT_NODE and \
+ (name == "*" or node.tagName == name):
+ rc.append(node)
+ _getElementsByTagNameHelper(node, name, rc)
+ return rc
+
+def _getElementsByTagNameNSHelper(parent, nsURI, localName, rc):
+ for node in parent.childNodes:
+ if node.nodeType == Node.ELEMENT_NODE:
+ if ((localName == "*" or node.localName == localName) and
+ (nsURI == "*" or node.namespaceURI == nsURI)):
+ rc.append(node)
+ _getElementsByTagNameNSHelper(node, nsURI, localName, rc)
+ return rc
+
+class DocumentFragment(Node):
+ nodeType = Node.DOCUMENT_FRAGMENT_NODE
+ nodeName = "#document-fragment"
+ nodeValue = None
+ attributes = None
+ parentNode = None
+ childNodeTypes = (Node.ELEMENT_NODE,
+ Node.TEXT_NODE,
+ Node.CDATA_SECTION_NODE,
+ Node.ENTITY_REFERENCE_NODE,
+ Node.PROCESSING_INSTRUCTION_NODE,
+ Node.COMMENT_NODE,
+ Node.NOTATION_NODE)
+
+
+class Attr(Node):
+ nodeType = Node.ATTRIBUTE_NODE
+ attributes = None
+ ownerElement = None
+ childNodeTypes = (Node.TEXT_NODE, Node.ENTITY_REFERENCE_NODE)
+
+ def __init__(self, qName, namespaceURI="", localName=None, prefix=None):
+ # skip setattr for performance
+ d = self.__dict__
+ d["localName"] = localName or qName
+ d["nodeName"] = d["name"] = qName
+ d["namespaceURI"] = namespaceURI
+ d["prefix"] = prefix
+ Node.__init__(self)
+ # nodeValue and value are set elsewhere
+
+ def __setattr__(self, name, value):
+ d = self.__dict__
+ if name in ("value", "nodeValue"):
+ d["value"] = d["nodeValue"] = value
+ elif name in ("name", "nodeName"):
+ d["name"] = d["nodeName"] = value
+ else:
+ d[name] = value
+
+ def cloneNode(self, deep):
+ clone = Node.cloneNode(self, deep)
+ if clone.__dict__.has_key("ownerElement"):
+ del clone.ownerElement
+ return clone
+
+
+class NamedNodeMap:
+ """The attribute list is a transient interface to the underlying
+ dictionaries. Mutations here will change the underlying element's
+ dictionary.
+
+ Ordering is imposed artificially and does not reflect the order of
+ attributes as found in an input document.
+ """
+
+ def __init__(self, attrs, attrsNS):
+ self._attrs = attrs
+ self._attrsNS = attrsNS
+
+ def __getattr__(self, name):
+ if name == "length":
+ return len(self._attrs)
+ raise AttributeError, name
+
+ def item(self, index):
+ try:
+ return self[self._attrs.keys()[index]]
+ except IndexError:
+ return None
+
+ def items(self):
+ L = []
+ for node in self._attrs.values():
+ L.append((node.nodeName, node.value))
+ return L
+
+ def itemsNS(self):
+ L = []
+ for node in self._attrs.values():
+ L.append(((node.URI, node.localName), node.value))
+ return L
+
+ def keys(self):
+ return self._attrs.keys()
+
+ def keysNS(self):
+ return self._attrsNS.keys()
+
+ def values(self):
+ return self._attrs.values()
+
+ def get(self, name, value = None):
+ return self._attrs.get(name, value)
+
+ def __len__(self):
+ return self.length
+
+ def __cmp__(self, other):
+ if self._attrs is getattr(other, "_attrs", None):
+ return 0
+ else:
+ return cmp(id(self), id(other))
+
+ #FIXME: is it appropriate to return .value?
+ def __getitem__(self, attname_or_tuple):
+ if type(attname_or_tuple) is _TupleType:
+ return self._attrsNS[attname_or_tuple]
+ else:
+ return self._attrs[attname_or_tuple]
+
+ # same as set
+ def __setitem__(self, attname, value):
+ if type(value) in _StringTypes:
+ node = Attr(attname)
+ node.value = value
+ else:
+ if not isinstance(value, Attr):
+ raise TypeError, "value must be a string or Attr object"
+ node = value
+ self.setNamedItem(node)
+
+ def setNamedItem(self, node):
+ if not isinstance(node, Attr):
+ raise HierarchyRequestErr, \
+ "%s cannot be child of %s" % (repr(node), repr(self))
+ old = self._attrs.get(node.name)
+ if old:
+ old.unlink()
+ self._attrs[node.name] = node
+ self._attrsNS[(node.namespaceURI, node.localName)] = node
+ return old
+
+ def setNamedItemNS(self, node):
+ return self.setNamedItem(node)
+
+ def __delitem__(self, attname_or_tuple):
+ node = self[attname_or_tuple]
+ node.unlink()
+ del self._attrs[node.name]
+ del self._attrsNS[(node.namespaceURI, node.localName)]
+ self.length = len(self._attrs)
+
+AttributeList = NamedNodeMap
+
+
+class Element(Node):
+ nodeType = Node.ELEMENT_NODE
+ nextSibling = None
+ previousSibling = None
+ childNodeTypes = (Node.ELEMENT_NODE, Node.PROCESSING_INSTRUCTION_NODE,
+ Node.COMMENT_NODE, Node.TEXT_NODE,
+ Node.CDATA_SECTION_NODE, Node.ENTITY_REFERENCE_NODE)
+
+ def __init__(self, tagName, namespaceURI=None, prefix="",
+ localName=None):
+ Node.__init__(self)
+ self.tagName = self.nodeName = tagName
+ self.localName = localName or tagName
+ self.prefix = prefix
+ self.namespaceURI = namespaceURI
+ self.nodeValue = None
+
+ self._attrs = {} # attributes are double-indexed:
+ self._attrsNS = {} # tagName -> Attribute
+ # URI,localName -> Attribute
+ # in the future: consider lazy generation
+ # of attribute objects this is too tricky
+ # for now because of headaches with
+ # namespaces.
+
+ def cloneNode(self, deep):
+ clone = Node.cloneNode(self, deep)
+ clone._attrs = {}
+ clone._attrsNS = {}
+ for attr in self._attrs.values():
+ node = attr.cloneNode(1)
+ clone._attrs[node.name] = node
+ clone._attrsNS[(node.namespaceURI, node.localName)] = node
+ node.ownerElement = clone
+ return clone
+
+ def unlink(self):
+ for attr in self._attrs.values():
+ attr.unlink()
+ self._attrs = None
+ self._attrsNS = None
+ Node.unlink(self)
+
+ def getAttribute(self, attname):
+ try:
+ return self._attrs[attname].value
+ except KeyError:
+ return ""
+
+ def getAttributeNS(self, namespaceURI, localName):
+ try:
+ return self._attrsNS[(namespaceURI, localName)].value
+ except KeyError:
+ return ""
+
+ def setAttribute(self, attname, value):
+ attr = Attr(attname)
+ # for performance
+ attr.__dict__["value"] = attr.__dict__["nodeValue"] = value
+ self.setAttributeNode(attr)
+
+ def setAttributeNS(self, namespaceURI, qualifiedName, value):
+ prefix, localname = _nssplit(qualifiedName)
+ # for performance
+ attr = Attr(qualifiedName, namespaceURI, localname, prefix)
+ attr.__dict__["value"] = attr.__dict__["nodeValue"] = value
+ self.setAttributeNode(attr)
+
+ def getAttributeNode(self, attrname):
+ return self._attrs.get(attrname)
+
+ def getAttributeNodeNS(self, namespaceURI, localName):
+ return self._attrsNS.get((namespaceURI, localName))
+
+ def setAttributeNode(self, attr):
+ if attr.ownerElement not in (None, self):
+ raise xml.dom.InuseAttributeErr("attribute node already owned")
+ old = self._attrs.get(attr.name, None)
+ if old:
+ old.unlink()
+ self._attrs[attr.name] = attr
+ self._attrsNS[(attr.namespaceURI, attr.localName)] = attr
+
+ # This creates a circular reference, but Element.unlink()
+ # breaks the cycle since the references to the attribute
+ # dictionaries are tossed.
+ attr.ownerElement = self
+
+ if old is not attr:
+ # It might have already been part of this node, in which case
+ # it doesn't represent a change, and should not be returned.
+ return old
+
+ setAttributeNodeNS = setAttributeNode
+
+ def removeAttribute(self, name):
+ attr = self._attrs[name]
+ self.removeAttributeNode(attr)
+
+ def removeAttributeNS(self, namespaceURI, localName):
+ attr = self._attrsNS[(namespaceURI, localName)]
+ self.removeAttributeNode(attr)
+
+ def removeAttributeNode(self, node):
+ node.unlink()
+ del self._attrs[node.name]
+ del self._attrsNS[(node.namespaceURI, node.localName)]
+
+ removeAttributeNodeNS = removeAttributeNode
+
+ def hasAttribute(self, name):
+ return self._attrs.has_key(name)
+
+ def hasAttributeNS(self, namespaceURI, localName):
+ return self._attrsNS.has_key((namespaceURI, localName))
+
+ def getElementsByTagName(self, name):
+ return _getElementsByTagNameHelper(self, name, [])
+
+ def getElementsByTagNameNS(self, namespaceURI, localName):
+ return _getElementsByTagNameNSHelper(self, namespaceURI, localName, [])
+
+ def __repr__(self):
+ return "<DOM Element: %s at %s>" % (self.tagName, id(self))
+
+ def writexml(self, writer, indent="", addindent="", newl=""):
+ # indent = current indentation
+ # addindent = indentation to add to higher levels
+ # newl = newline string
+ writer.write(indent+"<" + self.tagName)
+
+ attrs = self._get_attributes()
+ a_names = attrs.keys()
+ a_names.sort()
+
+ for a_name in a_names:
+ writer.write(" %s=\"" % a_name)
+ _write_data(writer, attrs[a_name].value)
+ writer.write("\"")
+ if self.childNodes:
+ writer.write(">%s"%(newl))
+ for node in self.childNodes:
+ node.writexml(writer,indent+addindent,addindent,newl)
+ writer.write("%s</%s>%s" % (indent,self.tagName,newl))
+ else:
+ writer.write("/>%s"%(newl))
+
+ def _get_attributes(self):
+ return AttributeList(self._attrs, self._attrsNS)
+
+ def hasAttributes(self):
+ if self._attrs or self._attrsNS:
+ return 1
+ else:
+ return 0
+
+class Comment(Node):
+ nodeType = Node.COMMENT_NODE
+ nodeName = "#comment"
+ attributes = None
+ childNodeTypes = ()
+
+ def __init__(self, data):
+ Node.__init__(self)
+ self.data = self.nodeValue = data
+
+ def writexml(self, writer, indent="", addindent="", newl=""):
+ writer.write("%s<!--%s-->%s" % (indent,self.data,newl))
+
+class ProcessingInstruction(Node):
+ nodeType = Node.PROCESSING_INSTRUCTION_NODE
+ attributes = None
+ childNodeTypes = ()
+
+ def __init__(self, target, data):
+ Node.__init__(self)
+ self.target = self.nodeName = target
+ self.data = self.nodeValue = data
+
+ def writexml(self, writer, indent="", addindent="", newl=""):
+ writer.write("%s<?%s %s?>%s" % (indent,self.target, self.data, newl))
+
+class CharacterData(Node):
+ def __init__(self, data):
+ if type(data) not in _StringTypes:
+ raise TypeError, "node contents must be a string"
+ Node.__init__(self)
+ self.data = self.nodeValue = data
+ self.length = len(data)
+
+ def __repr__(self):
+ if len(self.data) > 10:
+ dotdotdot = "..."
+ else:
+ dotdotdot = ""
+ return "<DOM %s node \"%s%s\">" % (
+ self.__class__.__name__, self.data[0:10], dotdotdot)
+
+ def substringData(self, offset, count):
+ if offset < 0:
+ raise xml.dom.IndexSizeErr("offset cannot be negative")
+ if offset >= len(self.data):
+ raise xml.dom.IndexSizeErr("offset cannot be beyond end of data")
+ if count < 0:
+ raise xml.dom.IndexSizeErr("count cannot be negative")
+ return self.data[offset:offset+count]
+
+ def appendData(self, arg):
+ self.data = self.data + arg
+ self.nodeValue = self.data
+ self.length = len(self.data)
+
+ def insertData(self, offset, arg):
+ if offset < 0:
+ raise xml.dom.IndexSizeErr("offset cannot be negative")
+ if offset >= len(self.data):
+ raise xml.dom.IndexSizeErr("offset cannot be beyond end of data")
+ if arg:
+ self.data = "%s%s%s" % (
+ self.data[:offset], arg, self.data[offset:])
+ self.nodeValue = self.data
+ self.length = len(self.data)
+
+ def deleteData(self, offset, count):
+ if offset < 0:
+ raise xml.dom.IndexSizeErr("offset cannot be negative")
+ if offset >= len(self.data):
+ raise xml.dom.IndexSizeErr("offset cannot be beyond end of data")
+ if count < 0:
+ raise xml.dom.IndexSizeErr("count cannot be negative")
+ if count:
+ self.data = self.data[:offset] + self.data[offset+count:]
+ self.nodeValue = self.data
+ self.length = len(self.data)
+
+ def replaceData(self, offset, count, arg):
+ if offset < 0:
+ raise xml.dom.IndexSizeErr("offset cannot be negative")
+ if offset >= len(self.data):
+ raise xml.dom.IndexSizeErr("offset cannot be beyond end of data")
+ if count < 0:
+ raise xml.dom.IndexSizeErr("count cannot be negative")
+ if count:
+ self.data = "%s%s%s" % (
+ self.data[:offset], arg, self.data[offset+count:])
+ self.nodeValue = self.data
+ self.length = len(self.data)
+
+class Text(CharacterData):
+ nodeType = Node.TEXT_NODE
+ nodeName = "#text"
+ attributes = None
+ childNodeTypes = ()
+
+ def splitText(self, offset):
+ if offset < 0 or offset > len(self.data):
+ raise xml.dom.IndexSizeErr("illegal offset value")
+ newText = Text(self.data[offset:])
+ next = self.nextSibling
+ if self.parentNode and self in self.parentNode.childNodes:
+ if next is None:
+ self.parentNode.appendChild(newText)
+ else:
+ self.parentNode.insertBefore(newText, next)
+ self.data = self.data[:offset]
+ self.nodeValue = self.data
+ self.length = len(self.data)
+ return newText
+
+ def writexml(self, writer, indent="", addindent="", newl=""):
+ _write_data(writer, "%s%s%s"%(indent, self.data, newl))
+
+
+class CDATASection(Text):
+ nodeType = Node.CDATA_SECTION_NODE
+ nodeName = "#cdata-section"
+
+ def writexml(self, writer, indent="", addindent="", newl=""):
+ _write_data(writer, "<![CDATA[%s]]>" % self.data)
+
+
+def _nssplit(qualifiedName):
+ fields = _string.split(qualifiedName, ':', 1)
+ if len(fields) == 2:
+ return fields
+ elif len(fields) == 1:
+ return ('', fields[0])
+
+
+class DocumentType(Node):
+ nodeType = Node.DOCUMENT_TYPE_NODE
+ nodeValue = None
+ attributes = None
+ name = None
+ publicId = None
+ systemId = None
+ internalSubset = None
+ entities = None
+ notations = None
+
+ def __init__(self, qualifiedName):
+ Node.__init__(self)
+ if qualifiedName:
+ prefix, localname = _nssplit(qualifiedName)
+ self.name = localname
+
+
+class DOMImplementation:
+ def hasFeature(self, feature, version):
+ if version not in ("1.0", "2.0"):
+ return 0
+ feature = _string.lower(feature)
+ return feature == "core"
+
+ def createDocument(self, namespaceURI, qualifiedName, doctype):
+ if doctype and doctype.parentNode is not None:
+ raise xml.dom.WrongDocumentErr(
+ "doctype object owned by another DOM tree")
+ doc = self._createDocument()
+ if doctype is None:
+ doctype = self.createDocumentType(qualifiedName, None, None)
+ if not qualifiedName:
+ # The spec is unclear what to raise here; SyntaxErr
+ # would be the other obvious candidate. Since Xerces raises
+ # InvalidCharacterErr, and since SyntaxErr is not listed
+ # for createDocument, that seems to be the better choice.
+ # XXX: need to check for illegal characters here and in
+ # createElement.
+ raise xml.dom.InvalidCharacterErr("Element with no name")
+ prefix, localname = _nssplit(qualifiedName)
+ if prefix == "xml" \
+ and namespaceURI != "http://www.w3.org/XML/1998/namespace":
+ raise xml.dom.NamespaceErr("illegal use of 'xml' prefix")
+ if prefix and not namespaceURI:
+ raise xml.dom.NamespaceErr(
+ "illegal use of prefix without namespaces")
+ element = doc.createElementNS(namespaceURI, qualifiedName)
+ doc.appendChild(element)
+ doctype.parentNode = doctype.ownerDocument = doc
+ doc.doctype = doctype
+ doc.implementation = self
+ return doc
+
+ def createDocumentType(self, qualifiedName, publicId, systemId):
+ doctype = DocumentType(qualifiedName)
+ doctype.publicId = publicId
+ doctype.systemId = systemId
+ return doctype
+
+ # internal
+ def _createDocument(self):
+ return Document()
+
+class Document(Node):
+ nodeType = Node.DOCUMENT_NODE
+ nodeName = "#document"
+ nodeValue = None
+ attributes = None
+ doctype = None
+ parentNode = None
+ previousSibling = nextSibling = None
+
+ implementation = DOMImplementation()
+ childNodeTypes = (Node.ELEMENT_NODE, Node.PROCESSING_INSTRUCTION_NODE,
+ Node.COMMENT_NODE, Node.DOCUMENT_TYPE_NODE)
+
+ def appendChild(self, node):
+ if node.nodeType not in self.childNodeTypes:
+ raise HierarchyRequestErr, \
+ "%s cannot be child of %s" % (repr(node), repr(self))
+ if node.parentNode is not None:
+ node.parentNode.removeChild(node)
+
+ if node.nodeType == Node.ELEMENT_NODE \
+ and self._get_documentElement():
+ raise xml.dom.HierarchyRequestErr(
+ "two document elements disallowed")
+ return Node.appendChild(self, node)
+
+ def removeChild(self, oldChild):
+ self.childNodes.remove(oldChild)
+ oldChild.nextSibling = oldChild.previousSibling = None
+ oldChild.parentNode = None
+ if self.documentElement is oldChild:
+ self.documentElement = None
+
+ return oldChild
+
+ def _get_documentElement(self):
+ for node in self.childNodes:
+ if node.nodeType == Node.ELEMENT_NODE:
+ return node
+
+ def unlink(self):
+ if self.doctype is not None:
+ self.doctype.unlink()
+ self.doctype = None
+ Node.unlink(self)
+
+ def createDocumentFragment(self):
+ d = DocumentFragment()
+ d.ownerDoc = self
+ return d
+
+ def createElement(self, tagName):
+ e = Element(tagName)
+ e.ownerDocument = self
+ return e
+
+ def createTextNode(self, data):
+ t = Text(data)
+ t.ownerDocument = self
+ return t
+
+ def createCDATASection(self, data):
+ c = CDATASection(data)
+ c.ownerDocument = self
+ return c
+
+ def createComment(self, data):
+ c = Comment(data)
+ c.ownerDocument = self
+ return c
+
+ def createProcessingInstruction(self, target, data):
+ p = ProcessingInstruction(target, data)
+ p.ownerDocument = self
+ return p
+
+ def createAttribute(self, qName):
+ a = Attr(qName)
+ a.ownerDocument = self
+ a.value = ""
+ return a
+
+ def createElementNS(self, namespaceURI, qualifiedName):
+ prefix, localName = _nssplit(qualifiedName)
+ e = Element(qualifiedName, namespaceURI, prefix, localName)
+ e.ownerDocument = self
+ return e
+
+ def createAttributeNS(self, namespaceURI, qualifiedName):
+ prefix, localName = _nssplit(qualifiedName)
+ a = Attr(qualifiedName, namespaceURI, localName, prefix)
+ a.ownerDocument = self
+ a.value = ""
+ return a
+
+ def getElementsByTagName(self, name):
+ return _getElementsByTagNameHelper(self, name, [])
+
+ def getElementsByTagNameNS(self, namespaceURI, localName):
+ return _getElementsByTagNameNSHelper(self, namespaceURI, localName, [])
+
+ def writexml(self, writer, indent="", addindent="", newl=""):
+ writer.write('<?xml version="1.0" ?>\n')
+ for node in self.childNodes:
+ node.writexml(writer, indent, addindent, newl)
+
+def _get_StringIO():
+ # we can't use cStringIO since it doesn't support Unicode strings
+ from StringIO import StringIO
+ return StringIO()
+
+def _doparse(func, args, kwargs):
+ events = apply(func, args, kwargs)
+ toktype, rootNode = events.getEvent()
+ events.expandNode(rootNode)
+ events.clear()
+ return rootNode
+
+def parse(*args, **kwargs):
+ """Parse a file into a DOM by filename or file object."""
+ from xml.dom import pulldom
+ return _doparse(pulldom.parse, args, kwargs)
+
+def parseString(*args, **kwargs):
+ """Parse a file into a DOM from a string."""
+ from xml.dom import pulldom
+ return _doparse(pulldom.parseString, args, kwargs)
+
+def getDOMImplementation():
+ return Document.implementation
|