1# Copyright (c) 2011 Google Inc. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5"""Applies a fix to CR LF TAB handling in xml.dom. 6 7Fixes this: http://code.google.com/p/chromium/issues/detail?id=76293 8Working around this: http://bugs.python.org/issue5752 9TODO(bradnelson): Consider dropping this when we drop XP support. 10""" 11 12 13import xml.dom.minidom 14 15 16def _Replacement_write_data(writer, data, is_attrib=False): 17 """Writes datachars to writer.""" 18 data = data.replace("&", "&").replace("<", "<") 19 data = data.replace("\"", """).replace(">", ">") 20 if is_attrib: 21 data = data.replace( 22 "\r", "
").replace( 23 "\n", "
").replace( 24 "\t", "	") 25 writer.write(data) 26 27 28def _Replacement_writexml(self, writer, indent="", addindent="", newl=""): 29 # indent = current indentation 30 # addindent = indentation to add to higher levels 31 # newl = newline string 32 writer.write(indent+"<" + self.tagName) 33 34 attrs = self._get_attributes() 35 a_names = sorted(attrs.keys()) 36 37 for a_name in a_names: 38 writer.write(" %s=\"" % a_name) 39 _Replacement_write_data(writer, attrs[a_name].value, is_attrib=True) 40 writer.write("\"") 41 if self.childNodes: 42 writer.write(">%s" % newl) 43 for node in self.childNodes: 44 node.writexml(writer, indent + addindent, addindent, newl) 45 writer.write("%s</%s>%s" % (indent, self.tagName, newl)) 46 else: 47 writer.write("/>%s" % newl) 48 49 50class XmlFix(object): 51 """Object to manage temporary patching of xml.dom.minidom.""" 52 53 def __init__(self): 54 # Preserve current xml.dom.minidom functions. 55 self.write_data = xml.dom.minidom._write_data 56 self.writexml = xml.dom.minidom.Element.writexml 57 # Inject replacement versions of a function and a method. 58 xml.dom.minidom._write_data = _Replacement_write_data 59 xml.dom.minidom.Element.writexml = _Replacement_writexml 60 61 def Cleanup(self): 62 if self.write_data: 63 xml.dom.minidom._write_data = self.write_data 64 xml.dom.minidom.Element.writexml = self.writexml 65 self.write_data = None 66 67 def __del__(self): 68 self.Cleanup() 69