class Element(Node): preserveCase = 0 caseInsensitive = 1 nsprefixes = None namespace = '' def __init__(self, tagName, attributes=None, parentNode=None, filename=None, markpos=None, caseInsensitive=1, preserveCase=0, namespace=''): Node.__init__(self, parentNode) self.preserveCase = preserveCase or not caseInsensitive self.caseInsensitive = caseInsensitive if not preserveCase: tagName = tagName.lower() if attributes is None: self.attributes = {} else: self.attributes = attributes for k, v in self.attributes.items(): self.attributes[k] = unescape(v) if caseInsensitive: self.attributes = InsensitiveDict(self.attributes, preserve=preserveCase) self.endTagName = self.nodeName = self.tagName = tagName self._filename = filename self._markpos = markpos self.namespace = namespace def addPrefixes(self, pfxs): if self.nsprefixes is None: self.nsprefixes = pfxs else: self.nsprefixes.update(pfxs) def endTag(self, endTagName): if not self.preserveCase: endTagName = endTagName.lower() self.endTagName = endTagName def isEqualToElement(self, n): if self.caseInsensitive: return (self.attributes == n.attributes) and (self.nodeName.lower() == n.nodeName.lower()) return (self.attributes == n.attributes) and (self.nodeName == n.nodeName) def cloneNode(self, deep=0, parent=None): clone = Element( self.tagName, parentNode=parent, namespace=self.namespace, preserveCase=self.preserveCase, caseInsensitive=self.caseInsensitive) clone.attributes.update(self.attributes) if deep: clone.childNodes = [child.cloneNode(1, clone) for child in self.childNodes] else: clone.childNodes = [] return clone def getElementsByTagName(self, name): if self.caseInsensitive: return getElementsByTagNameNoCase(self, name) return getElementsByTagName(self, name) def hasAttributes(self): return 1 def getAttribute(self, name, default=None): return self.attributes.get(name, default) def getAttributeNS(self, ns, name, default=None): nsk = (ns, name) if self.attributes.has_key(nsk): return self.attributes[nsk] if ns == self.namespace: return self.attributes.get(name, default) return default def getAttributeNode(self, name): return _Attr(self.getAttribute(name), self) def setAttribute(self, name, attr): self.attributes[name] = attr def removeAttribute(self, name): if name in self.attributes: del self.attributes[name] def removeAttribute_has_key(self, name): if self.attributes.has_key(name): del self.attributes[name] def hasAttribute(self, name): return name in self.attributes def hasAttribute_has_key(self, name): return self.attributes.has_key(name) if dictsAreNotSequences: hasAttribute = hasAttribute_has_key removeAttribute = removeAttribute_has_key def writexml(self, stream, indent='', addindent='', newl='', strip=0, nsprefixes={}, namespace=''): # write beginning ALLOWSINGLETON = ('img', 'br', 'hr', 'base', 'meta', 'link', 'param', 'area', 'input', 'col', 'basefont', 'isindex', 'frame') BLOCKELEMENTS = ('html', 'head', 'body', 'noscript', 'ins', 'del', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'script', 'ul', 'ol', 'dl', 'pre', 'hr', 'blockquote', 'address', 'p', 'div', 'fieldset', 'table', 'tr', 'form', 'object', 'fieldset', 'applet', 'map') FORMATNICELY = ('tr', 'ul', 'ol', 'head') # this should never be necessary unless people start # changing .tagName on the fly(?) if not self.preserveCase: self.endTagName = self.tagName w = stream.write if self.nsprefixes: newprefixes = self.nsprefixes.copy() for ns in nsprefixes.keys(): del newprefixes[ns] else: newprefixes = {} begin = ['<'] if self.tagName in BLOCKELEMENTS: begin = [newl, indent] + begin bext = begin.extend writeattr = lambda _atr, _val: bext((' ', _atr, '="', escape(_val), '"')) if namespace != self.namespace and self.namespace: if nsprefixes.has_key(self.namespace): prefix = nsprefixes[self.namespace] bext(prefix+':'+self.tagName) else: bext(self.tagName) writeattr("xmlns", self.namespace) else: bext(self.tagName) j = ''.join for attr, val in self.attributes.iteritems(): if isinstance(attr, tuple): ns, key = attr if nsprefixes.has_key(ns): prefix = nsprefixes[ns] else: prefix = genprefix() newprefixes[ns] = prefix assert val is not None writeattr(prefix+':'+key,val) else: assert val is not None writeattr(attr, val) if newprefixes: for ns, prefix in newprefixes.iteritems(): if prefix: writeattr('xmlns:'+prefix, ns) newprefixes.update(nsprefixes) downprefixes = newprefixes else: downprefixes = nsprefixes w(j(begin)) if self.childNodes: w(">") newindent = indent + addindent for child in self.childNodes: if self.tagName in BLOCKELEMENTS and \ self.tagName in FORMATNICELY: w(j((newl, newindent))) child.writexml(stream, newindent, addindent, newl, strip, downprefixes, self.namespace) if self.tagName in BLOCKELEMENTS: w(j((newl, indent))) w(j(("</", self.endTagName, '>'))) elif self.tagName.lower() not in ALLOWSINGLETON: w(j(('></', self.endTagName, '>'))) else: w(" />") def __repr__(self): rep = "Element(%s" % repr(self.nodeName) if self.attributes: rep += ", attributes=%r" % (self.attributes,) if self._filename: rep += ", filename=%r" % (self._filename,) if self._markpos: rep += ", markpos=%r" % (self._markpos,) return rep + ')' def __str__(self): rep = "<" + self.nodeName if self._filename or self._markpos: rep += " (" if self._filename: rep += repr(self._filename) if self._markpos: rep += " line %s column %s" % self._markpos if self._filename or self._markpos: rep += ")" for item in self.attributes.items(): rep += " %s=%r" % item if self.hasChildNodes(): rep += " >...</%s>" % self.nodeName else: rep += " />" return rep
class Element(Node): preserveCase = 0 caseInsensitive = 1 nsprefixes = None def __init__(self, tagName, attributes=None, parentNode=None, filename=None, markpos=None, caseInsensitive=1, preserveCase=0, namespace=None): Node.__init__(self, parentNode) self.preserveCase = preserveCase or not caseInsensitive self.caseInsensitive = caseInsensitive if not preserveCase: tagName = tagName.lower() if attributes is None: self.attributes = {} else: self.attributes = attributes for k, v in self.attributes.items(): self.attributes[k] = unescape(v) if caseInsensitive: self.attributes = InsensitiveDict(self.attributes, preserve=preserveCase) self.endTagName = self.nodeName = self.tagName = tagName self._filename = filename self._markpos = markpos self.namespace = namespace def addPrefixes(self, pfxs): if self.nsprefixes is None: self.nsprefixes = pfxs else: self.nsprefixes.update(pfxs) def endTag(self, endTagName): if not self.preserveCase: endTagName = endTagName.lower() self.endTagName = endTagName def isEqualToElement(self, n): if self.caseInsensitive: return ((self.attributes == n.attributes) and (self.nodeName.lower() == n.nodeName.lower())) return (self.attributes == n.attributes) and (self.nodeName == n.nodeName) def isEqualToNode(self, other): """ Compare this element to C{other}. If the C{nodeName}, C{namespace}, C{attributes}, and C{childNodes} are all the same, return C{True}, otherwise return C{False}. """ return ( self.nodeName.lower() == other.nodeName.lower() and self.namespace == other.namespace and self.attributes == other.attributes and Node.isEqualToNode(self, other)) def cloneNode(self, deep=0, parent=None): clone = Element( self.tagName, parentNode=parent, namespace=self.namespace, preserveCase=self.preserveCase, caseInsensitive=self.caseInsensitive) clone.attributes.update(self.attributes) if deep: clone.childNodes = [child.cloneNode(1, clone) for child in self.childNodes] else: clone.childNodes = [] return clone def getElementsByTagName(self, name): if self.caseInsensitive: return getElementsByTagNameNoCase(self, name) return getElementsByTagName(self, name) def hasAttributes(self): return 1 def getAttribute(self, name, default=None): return self.attributes.get(name, default) def getAttributeNS(self, ns, name, default=None): nsk = (ns, name) if self.attributes.has_key(nsk): return self.attributes[nsk] if ns == self.namespace: return self.attributes.get(name, default) return default def getAttributeNode(self, name): return _Attr(self.getAttribute(name), self) def setAttribute(self, name, attr): self.attributes[name] = attr def removeAttribute(self, name): if name in self.attributes: del self.attributes[name] def hasAttribute(self, name): return name in self.attributes def writexml(self, stream, indent='', addindent='', newl='', strip=0, nsprefixes={}, namespace=''): """ Serialize this L{Element} to the given stream. @param stream: A file-like object to which this L{Element} will be written. @param nsprefixes: A C{dict} mapping namespace URIs as C{str} to prefixes as C{str}. This defines the prefixes which are already in scope in the document at the point at which this L{Element} exists. This is essentially an implementation detail for namespace support. Applications should not try to use it. @param namespace: The namespace URI as a C{str} which is the default at the point in the document at which this L{Element} exists. This is essentially an implementation detail for namespace support. Applications should not try to use it. """ # write beginning ALLOWSINGLETON = ('img', 'br', 'hr', 'base', 'meta', 'link', 'param', 'area', 'input', 'col', 'basefont', 'isindex', 'frame') BLOCKELEMENTS = ('html', 'head', 'body', 'noscript', 'ins', 'del', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'script', 'ul', 'ol', 'dl', 'pre', 'hr', 'blockquote', 'address', 'p', 'div', 'fieldset', 'table', 'tr', 'form', 'object', 'fieldset', 'applet', 'map') FORMATNICELY = ('tr', 'ul', 'ol', 'head') # this should never be necessary unless people start # changing .tagName on the fly(?) if not self.preserveCase: self.endTagName = self.tagName w = stream.write if self.nsprefixes: newprefixes = self.nsprefixes.copy() for ns in nsprefixes.keys(): if ns in newprefixes: del newprefixes[ns] else: newprefixes = {} begin = ['<'] if self.tagName in BLOCKELEMENTS: begin = [newl, indent] + begin bext = begin.extend writeattr = lambda _atr, _val: bext((' ', _atr, '="', escape(_val), '"')) # Make a local for tracking what end tag will be used. If namespace # prefixes are involved, this will be changed to account for that # before it's actually used. endTagName = self.endTagName if namespace != self.namespace and self.namespace is not None: # If the current default namespace is not the namespace of this tag # (and this tag has a namespace at all) then we'll write out # something related to namespaces. if self.namespace in nsprefixes: # This tag's namespace already has a prefix bound to it. Use # that prefix. prefix = nsprefixes[self.namespace] bext(prefix + ':' + self.tagName) # Also make sure we use it for the end tag. endTagName = prefix + ':' + self.endTagName else: # This tag's namespace has no prefix bound to it. Change the # default namespace to this tag's namespace so we don't need # prefixes. Alternatively, we could add a new prefix binding. # I'm not sure why the code was written one way rather than the # other. -exarkun bext(self.tagName) writeattr("xmlns", self.namespace) # The default namespace just changed. Make sure any children # know about this. namespace = self.namespace else: # This tag has no namespace or its namespace is already the default # namespace. Nothing extra to do here. bext(self.tagName) j = ''.join for attr, val in self.attributes.iteritems(): if isinstance(attr, tuple): ns, key = attr if nsprefixes.has_key(ns): prefix = nsprefixes[ns] else: prefix = genprefix() newprefixes[ns] = prefix assert val is not None writeattr(prefix+':'+key,val) else: assert val is not None writeattr(attr, val) if newprefixes: for ns, prefix in newprefixes.iteritems(): if prefix: writeattr('xmlns:'+prefix, ns) newprefixes.update(nsprefixes) downprefixes = newprefixes else: downprefixes = nsprefixes w(j(begin)) if self.childNodes: w(">") newindent = indent + addindent for child in self.childNodes: if self.tagName in BLOCKELEMENTS and \ self.tagName in FORMATNICELY: w(j((newl, newindent))) child.writexml(stream, newindent, addindent, newl, strip, downprefixes, namespace) if self.tagName in BLOCKELEMENTS: w(j((newl, indent))) w(j(('</', endTagName, '>'))) elif self.tagName.lower() not in ALLOWSINGLETON: w(j(('></', endTagName, '>'))) else: w(" />") def __repr__(self): rep = "Element(%s" % repr(self.nodeName) if self.attributes: rep += ", attributes=%r" % (self.attributes,) if self._filename: rep += ", filename=%r" % (self._filename,) if self._markpos: rep += ", markpos=%r" % (self._markpos,) return rep + ')' def __str__(self): rep = "<" + self.nodeName if self._filename or self._markpos: rep += " (" if self._filename: rep += repr(self._filename) if self._markpos: rep += " line %s column %s" % self._markpos if self._filename or self._markpos: rep += ")" for item in self.attributes.items(): rep += " %s=%r" % item if self.hasChildNodes(): rep += " >...</%s>" % self.nodeName else: rep += " />" return rep
class Element(Node): preserveCase = 0 caseInsensitive = 1 nsprefixes = None def __init__(self, tagName, attributes=None, parentNode=None, filename=None, markpos=None, caseInsensitive=1, preserveCase=0, namespace=None): Node.__init__(self, parentNode) self.preserveCase = preserveCase or not caseInsensitive self.caseInsensitive = caseInsensitive if not preserveCase: tagName = tagName.lower() if attributes is None: self.attributes = {} else: self.attributes = attributes for k, v in self.attributes.items(): self.attributes[k] = unescape(v) if caseInsensitive: self.attributes = InsensitiveDict(self.attributes, preserve=preserveCase) self.endTagName = self.nodeName = self.tagName = tagName self._filename = filename self._markpos = markpos self.namespace = namespace def addPrefixes(self, pfxs): if self.nsprefixes is None: self.nsprefixes = pfxs else: self.nsprefixes.update(pfxs) def endTag(self, endTagName): if not self.preserveCase: endTagName = endTagName.lower() self.endTagName = endTagName def isEqualToElement(self, n): if self.caseInsensitive: return ((self.attributes == n.attributes) and (self.nodeName.lower() == n.nodeName.lower())) return (self.attributes == n.attributes) and (self.nodeName == n.nodeName) def isEqualToNode(self, other): """ Compare this element to C{other}. If the C{nodeName}, C{namespace}, C{attributes}, and C{childNodes} are all the same, return C{True}, otherwise return C{False}. """ return (self.nodeName.lower() == other.nodeName.lower() and self.namespace == other.namespace and self.attributes == other.attributes and Node.isEqualToNode(self, other)) def cloneNode(self, deep=0, parent=None): clone = Element(self.tagName, parentNode=parent, namespace=self.namespace, preserveCase=self.preserveCase, caseInsensitive=self.caseInsensitive) clone.attributes.update(self.attributes) if deep: clone.childNodes = [ child.cloneNode(1, clone) for child in self.childNodes ] else: clone.childNodes = [] return clone def getElementsByTagName(self, name): if self.caseInsensitive: return getElementsByTagNameNoCase(self, name) return getElementsByTagName(self, name) def hasAttributes(self): return 1 def getAttribute(self, name, default=None): return self.attributes.get(name, default) def getAttributeNS(self, ns, name, default=None): nsk = (ns, name) if self.attributes.has_key(nsk): return self.attributes[nsk] if ns == self.namespace: return self.attributes.get(name, default) return default def getAttributeNode(self, name): return _Attr(self.getAttribute(name), self) def setAttribute(self, name, attr): self.attributes[name] = attr def removeAttribute(self, name): if name in self.attributes: del self.attributes[name] def hasAttribute(self, name): return name in self.attributes def writexml(self, stream, indent='', addindent='', newl='', strip=0, nsprefixes={}, namespace=''): # write beginning ALLOWSINGLETON = ('img', 'br', 'hr', 'base', 'meta', 'link', 'param', 'area', 'input', 'col', 'basefont', 'isindex', 'frame') BLOCKELEMENTS = ('html', 'head', 'body', 'noscript', 'ins', 'del', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'script', 'ul', 'ol', 'dl', 'pre', 'hr', 'blockquote', 'address', 'p', 'div', 'fieldset', 'table', 'tr', 'form', 'object', 'fieldset', 'applet', 'map') FORMATNICELY = ('tr', 'ul', 'ol', 'head') # this should never be necessary unless people start # changing .tagName on the fly(?) if not self.preserveCase: self.endTagName = self.tagName w = stream.write if self.nsprefixes: newprefixes = self.nsprefixes.copy() for ns in nsprefixes.keys(): if ns in newprefixes: del newprefixes[ns] else: newprefixes = {} begin = ['<'] if self.tagName in BLOCKELEMENTS: begin = [newl, indent] + begin bext = begin.extend writeattr = lambda _atr, _val: bext( (' ', _atr, '="', escape(_val), '"')) if namespace != self.namespace and self.namespace is not None: if nsprefixes.has_key(self.namespace): prefix = nsprefixes[self.namespace] bext(prefix + ':' + self.tagName) else: bext(self.tagName) writeattr("xmlns", self.namespace) else: bext(self.tagName) j = ''.join for attr, val in self.attributes.iteritems(): if isinstance(attr, tuple): ns, key = attr if nsprefixes.has_key(ns): prefix = nsprefixes[ns] else: prefix = genprefix() newprefixes[ns] = prefix assert val is not None writeattr(prefix + ':' + key, val) else: assert val is not None writeattr(attr, val) if newprefixes: for ns, prefix in newprefixes.iteritems(): if prefix: writeattr('xmlns:' + prefix, ns) newprefixes.update(nsprefixes) downprefixes = newprefixes else: downprefixes = nsprefixes w(j(begin)) if self.childNodes: w(">") newindent = indent + addindent for child in self.childNodes: if self.tagName in BLOCKELEMENTS and \ self.tagName in FORMATNICELY: w(j((newl, newindent))) child.writexml(stream, newindent, addindent, newl, strip, downprefixes, self.namespace) if self.tagName in BLOCKELEMENTS: w(j((newl, indent))) w(j(("</", self.endTagName, '>'))) elif self.tagName.lower() not in ALLOWSINGLETON: w(j(('></', self.endTagName, '>'))) else: w(" />") def __repr__(self): rep = "Element(%s" % repr(self.nodeName) if self.attributes: rep += ", attributes=%r" % (self.attributes, ) if self._filename: rep += ", filename=%r" % (self._filename, ) if self._markpos: rep += ", markpos=%r" % (self._markpos, ) return rep + ')' def __str__(self): rep = "<" + self.nodeName if self._filename or self._markpos: rep += " (" if self._filename: rep += repr(self._filename) if self._markpos: rep += " line %s column %s" % self._markpos if self._filename or self._markpos: rep += ")" for item in self.attributes.items(): rep += " %s=%r" % item if self.hasChildNodes(): rep += " >...</%s>" % self.nodeName else: rep += " />" return rep
# enable: W9602 # an example of call has_key on a dict # a warning should be generated if {}.has_key("bar"): pass foo = {} if foo.has_key("bar"): pass # an example of call has_key on a existing class # no warnings should be showed in this case from twisted.python.util import InsensitiveDict bar = InsensitiveDict() if bar.has_key("bar"): pass # an example of call has_key on a unknown object # no warnings should be showed as we do not know what it is result = baz.has_key("bar")