xml_fix.py 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  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. """Applies a fix to CR LF TAB handling in xml.dom.
  5. Fixes this: http://code.google.com/p/chromium/issues/detail?id=76293
  6. Working around this: http://bugs.python.org/issue5752
  7. TODO(bradnelson): Consider dropping this when we drop XP support.
  8. """
  9. import xml.dom.minidom
  10. def _Replacement_write_data(writer, data, is_attrib=False):
  11. """Writes datachars to writer."""
  12. data = data.replace("&", "&amp;").replace("<", "&lt;")
  13. data = data.replace("\"", "&quot;").replace(">", "&gt;")
  14. if is_attrib:
  15. data = data.replace(
  16. "\r", "&#xD;").replace(
  17. "\n", "&#xA;").replace(
  18. "\t", "&#x9;")
  19. writer.write(data)
  20. def _Replacement_writexml(self, writer, indent="", addindent="", newl=""):
  21. # indent = current indentation
  22. # addindent = indentation to add to higher levels
  23. # newl = newline string
  24. writer.write(indent+"<" + self.tagName)
  25. attrs = self._get_attributes()
  26. a_names = attrs.keys()
  27. a_names.sort()
  28. for a_name in a_names:
  29. writer.write(" %s=\"" % a_name)
  30. _Replacement_write_data(writer, attrs[a_name].value, is_attrib=True)
  31. writer.write("\"")
  32. if self.childNodes:
  33. writer.write(">%s" % newl)
  34. for node in self.childNodes:
  35. node.writexml(writer, indent + addindent, addindent, newl)
  36. writer.write("%s</%s>%s" % (indent, self.tagName, newl))
  37. else:
  38. writer.write("/>%s" % newl)
  39. class XmlFix(object):
  40. """Object to manage temporary patching of xml.dom.minidom."""
  41. def __init__(self):
  42. # Preserve current xml.dom.minidom functions.
  43. self.write_data = xml.dom.minidom._write_data
  44. self.writexml = xml.dom.minidom.Element.writexml
  45. # Inject replacement versions of a function and a method.
  46. xml.dom.minidom._write_data = _Replacement_write_data
  47. xml.dom.minidom.Element.writexml = _Replacement_writexml
  48. def Cleanup(self):
  49. if self.write_data:
  50. xml.dom.minidom._write_data = self.write_data
  51. xml.dom.minidom.Element.writexml = self.writexml
  52. self.write_data = None
  53. def __del__(self):
  54. self.Cleanup()