def __init__(self, node, write, **kw): self.unsuppressedPrefixes = kw.get('unsuppressedPrefixes') self._exclusive = None if node.nodeType == Node.ELEMENT_NODE: if not c14n._inclusive(self): self._exclusive = self._inherit_context(node) c14n._implementation.__init__(self, node, write, **kw)
def _do_element(self, node, initial_other_attrs=[]): """Patch for the xml.dom.ext.c14n implemenation _do_element method. This fixes a problem with sorting of namespaces. """ # Get state (from the stack) make local copies. # ns_parent -- NS declarations in parent # ns_rendered -- NS nodes rendered by ancestors # ns_local -- NS declarations relevant to this element # xml_attrs -- Attributes in XML namespace from parent # xml_attrs_local -- Local attributes in XML namespace. ns_parent, ns_rendered, xml_attrs = \ self.state[0], self.state[1].copy(), self.state[2].copy() #0422 ns_local = ns_parent.copy() xml_attrs_local = {} # Divide attributes into NS, XML, and others. #other_attrs = initial_other_attrs[:] other_attrs = [] sort_these_attrs = initial_other_attrs[:] in_subset = c14n._in_subset(self.subset, node) #for a in _attrs(node): sort_these_attrs += c14n._attrs(node) for a in sort_these_attrs: if a.namespaceURI == c14n.XMLNS.BASE: n = a.nodeName if n == "xmlns:": n = "xmlns" # DOM bug workaround ns_local[n] = a.nodeValue elif a.namespaceURI == c14n.XMLNS.XML: if c14n._inclusive(self) or ( in_subset and c14n._in_subset(self.subset, a) ): #020925 Test to see if attribute node in subset xml_attrs_local[a.nodeName] = a #0426 else: if c14n._in_subset( self.subset, a ): #020925 Test to see if attribute node in subset other_attrs.append(a) #add local xml:foo attributes to ancestor's xml:foo attributes xml_attrs.update(xml_attrs_local) # Render the node W, name = self.write, None if in_subset: name = node.nodeName W('<') W(name) # Create list of NS attributes to render. ns_to_render = [] for n, v in ns_local.items(): # If default namespace is XMLNS.BASE or empty, # and if an ancestor was the same if n == "xmlns" and v in [ c14n.XMLNS.BASE, '' ] \ and ns_rendered.get('xmlns') in [ c14n.XMLNS.BASE, '', None ]: continue # "omit namespace node with local name xml, which defines # the xml prefix, if its string value is # http://www.w3.org/XML/1998/namespace." if n in ["xmlns:xml", "xml"] \ and v in [ 'http://www.w3.org/XML/1998/namespace' ]: continue # If not previously rendered # and it's inclusive or utilized if (n,v) not in ns_rendered.items() \ and (c14n._inclusive(self) or \ c14n._utilized(n, node, other_attrs, self.unsuppressedPrefixes)): ns_to_render.append((n, v)) ##################################### # JRB ##################################### if not c14n._inclusive(self): if node.prefix is None: look_for = [ ('xmlns', node.namespaceURI), ] else: look_for = [ ('xmlns:%s' % node.prefix, node.namespaceURI), ] for a in c14n._attrs(node): if a.namespaceURI != XMLNS.BASE: #print "ATTRIBUTE: ", (a.namespaceURI, a.prefix) if a.prefix: #print "APREFIX: ", a.prefix look_for.append( ('xmlns:%s' % a.prefix, a.namespaceURI)) for key, namespaceURI in look_for: if ns_rendered.has_key(key): if ns_rendered[key] == namespaceURI: # Dont write out pass else: #ns_to_render += [(key, namespaceURI)] pass elif (key, namespaceURI) in ns_to_render: # Dont write out pass else: # Unique write out, rewrite to render ns_local[key] = namespaceURI for a in self._exclusive: if a.nodeName == key: #self._do_attr(a.nodeName, a.value) #ns_rendered[key] = namespaceURI #break ns_to_render += [(a.nodeName, a.value)] break elif key is None and a.nodeName == 'xmlns': #print "DEFAULT: ", (a.nodeName, a.value) ns_to_render += [(a.nodeName, a.value)] break #print "KEY: ", key else: #print "Look for: ", look_for #print "NS_TO_RENDER: ", ns_to_render #print "EXCLUSIVE NS: ", map(lambda f: (f.nodeName,f.value),self._exclusive) raise RuntimeError, \ 'can not find namespace (%s="%s") for exclusive canonicalization'\ %(key, namespaceURI) ##################################### # Sort and render the ns, marking what was rendered. ns_to_render.sort(c14n._sorter_ns) for n, v in ns_to_render: #XXX JRB, getting 'xmlns,None' here when xmlns='' if v: self._do_attr(n, v) else: v = '' self._do_attr(n, v) ns_rendered[n] = v #0417 # If exclusive or the parent is in the subset, add the local xml attributes # Else, add all local and ancestor xml attributes # Sort and render the attributes. if not c14n._inclusive(self) or c14n._in_subset( self.subset, node.parentNode): #0426 other_attrs.extend(xml_attrs_local.values()) else: other_attrs.extend(xml_attrs.values()) #print "OTHER: ", other_attrs other_attrs.sort(c14n._sorter) for a in other_attrs: self._do_attr(a.nodeName, a.value) W('>') # Push state, recurse, pop state. state, self.state = self.state, (ns_local, ns_rendered, xml_attrs) for c in c14n._children(node): c14n._implementation.handlers[c.nodeType](self, c) self.state = state if name: W('</%s>' % name)
def _do_element(self, node, initial_other_attrs = []): """Patch for the xml.dom.ext.c14n implemenation _do_element method. This fixes a problem with sorting of namespaces. """ # Get state (from the stack) make local copies. # ns_parent -- NS declarations in parent # ns_rendered -- NS nodes rendered by ancestors # ns_local -- NS declarations relevant to this element # xml_attrs -- Attributes in XML namespace from parent # xml_attrs_local -- Local attributes in XML namespace. ns_parent, ns_rendered, xml_attrs = \ self.state[0], self.state[1].copy(), self.state[2].copy() #0422 ns_local = ns_parent.copy() xml_attrs_local = {} # Divide attributes into NS, XML, and others. #other_attrs = initial_other_attrs[:] other_attrs = [] sort_these_attrs = initial_other_attrs[:] in_subset = c14n._in_subset(self.subset, node) #for a in _attrs(node): sort_these_attrs +=c14n._attrs(node) for a in sort_these_attrs: if a.namespaceURI == c14n.XMLNS.BASE: n = a.nodeName if n == "xmlns:": n = "xmlns" # DOM bug workaround ns_local[n] = a.nodeValue elif a.namespaceURI == c14n.XMLNS.XML: if c14n._inclusive(self) or (in_subset and c14n._in_subset(self.subset, a)): #020925 Test to see if attribute node in subset xml_attrs_local[a.nodeName] = a #0426 else: if c14n._in_subset(self.subset, a): #020925 Test to see if attribute node in subset other_attrs.append(a) #add local xml:foo attributes to ancestor's xml:foo attributes xml_attrs.update(xml_attrs_local) # Render the node W, name = self.write, None if in_subset: name = node.nodeName W('<') W(name) # Create list of NS attributes to render. ns_to_render = [] for n,v in ns_local.items(): # If default namespace is XMLNS.BASE or empty, # and if an ancestor was the same if n == "xmlns" and v in [ c14n.XMLNS.BASE, '' ] \ and ns_rendered.get('xmlns') in [ c14n.XMLNS.BASE, '', None ]: continue # "omit namespace node with local name xml, which defines # the xml prefix, if its string value is # http://www.w3.org/XML/1998/namespace." if n in ["xmlns:xml", "xml"] \ and v in [ 'http://www.w3.org/XML/1998/namespace' ]: continue # If not previously rendered # and it's inclusive or utilized if (n,v) not in ns_rendered.items() \ and (c14n._inclusive(self) or \ c14n._utilized(n, node, other_attrs, self.unsuppressedPrefixes)): ns_to_render.append((n, v)) ##################################### # JRB ##################################### if not c14n._inclusive(self): if node.prefix is None: look_for = [('xmlns', node.namespaceURI),] else: look_for = [('xmlns:%s' %node.prefix, node.namespaceURI),] for a in c14n._attrs(node): if a.namespaceURI != XMLNS.BASE: #print "ATTRIBUTE: ", (a.namespaceURI, a.prefix) if a.prefix: #print "APREFIX: ", a.prefix look_for.append(('xmlns:%s' %a.prefix, a.namespaceURI)) for key,namespaceURI in look_for: if ns_rendered.has_key(key): if ns_rendered[key] == namespaceURI: # Dont write out pass else: #ns_to_render += [(key, namespaceURI)] pass elif (key,namespaceURI) in ns_to_render: # Dont write out pass else: # Unique write out, rewrite to render ns_local[key] = namespaceURI for a in self._exclusive: if a.nodeName == key: #self._do_attr(a.nodeName, a.value) #ns_rendered[key] = namespaceURI #break ns_to_render += [(a.nodeName, a.value)] break elif key is None and a.nodeName == 'xmlns': #print "DEFAULT: ", (a.nodeName, a.value) ns_to_render += [(a.nodeName, a.value)] break #print "KEY: ", key else: #print "Look for: ", look_for #print "NS_TO_RENDER: ", ns_to_render #print "EXCLUSIVE NS: ", map(lambda f: (f.nodeName,f.value),self._exclusive) raise RuntimeError, \ 'can not find namespace (%s="%s") for exclusive canonicalization'\ %(key, namespaceURI) ##################################### # Sort and render the ns, marking what was rendered. ns_to_render.sort(c14n._sorter_ns) for n,v in ns_to_render: #XXX JRB, getting 'xmlns,None' here when xmlns='' if v: self._do_attr(n, v) else: v = '' self._do_attr(n, v) ns_rendered[n]=v #0417 # If exclusive or the parent is in the subset, add the local xml attributes # Else, add all local and ancestor xml attributes # Sort and render the attributes. if not c14n._inclusive(self) or c14n._in_subset(self.subset,node.parentNode): #0426 other_attrs.extend(xml_attrs_local.values()) else: other_attrs.extend(xml_attrs.values()) #print "OTHER: ", other_attrs other_attrs.sort(c14n._sorter) for a in other_attrs: self._do_attr(a.nodeName, a.value) W('>') # Push state, recurse, pop state. state, self.state = self.state, (ns_local, ns_rendered, xml_attrs) for c in c14n._children(node): c14n._implementation.handlers[c.nodeType](self, c) self.state = state if name: W('</%s>' % name)