Lowercase initial word in some log messages.
[hooke.git] / hooke / compat / minidom.py
1 # Copyright (C) 2010 W. Trevor King <wking@drexel.edu>
2 #
3 # This file is part of Hooke.
4 #
5 # Hooke is free software: you can redistribute it and/or modify it
6 # under the terms of the GNU Lesser General Public License as
7 # published by the Free Software Foundation, either version 3 of the
8 # License, or (at your option) any later version.
9 #
10 # Hooke is distributed in the hope that it will be useful, but WITHOUT
11 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 # or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General
13 # Public License for more details.
14 #
15 # You should have received a copy of the GNU Lesser General Public
16 # License along with Hooke.  If not, see
17 # <http://www.gnu.org/licenses/>.
18
19 """Dynamically patch :mod:`xml.dom.minidom`'s attribute value escaping.
20
21 :meth:`xml.dom.minidom.Element.setAttribute` doesn't preform some
22 character escaping (see the `Python bug`_ and `XML specs`_).
23 Importing this module applies the suggested patch dynamically.
24
25 .. _Python bug: http://bugs.python.org/issue5752
26 .. _XML specs:
27   http://www.w3.org/TR/2000/WD-xml-c14n-20000119.html#charescaping
28 """
29
30 import logging
31 import xml.dom.minidom
32
33
34 def _write_data(writer, data, isAttrib=False):
35     "Writes datachars to writer."
36     if isAttrib:
37         data = data.replace("\r", "&#xD;").replace("\n", "&#xA;")
38         data = data.replace("\t", "&#x9;").replace('"', "&quot;")
39     writer.write(data)
40 xml.dom.minidom._write_data = _write_data
41
42 def writexml(self, writer, indent="", addindent="", newl=""):
43     # indent = current indentation
44     # addindent = indentation to add to higher levels
45     # newl = newline string
46     writer.write(indent+"<" + self.tagName)
47
48     attrs = self._get_attributes()
49     a_names = attrs.keys()
50     a_names.sort()
51
52     for a_name in a_names:
53         writer.write(" %s=\"" % a_name)
54         _write_data(writer, attrs[a_name].value, isAttrib=True)
55         writer.write("\"")
56     if self.childNodes:
57         writer.write(">%s"%(newl))
58         for node in self.childNodes:
59             node.writexml(writer,indent+addindent,addindent,newl)
60         writer.write("%s</%s>%s" % (indent,self.tagName,newl))
61     else:
62         writer.write("/>%s"%(newl))
63 # For an introduction to overriding instance methods, see
64 #   http://irrepupavel.com/documents/python/instancemethod/
65 instancemethod = type(xml.dom.minidom.Element.writexml)
66 xml.dom.minidom.Element.writexml = instancemethod(
67     writexml, None, xml.dom.minidom.Element)
68
69 logging.warn(
70     'monkey patched xml.dom.minidom.Element and ._write_data for issue5752')