Also escape quotes (") in minidom's _write_data.
[hooke.git] / hooke / compat / minidom.py
1 # Copyright
2
3 """Dynamically patch :mod:`xml.dom.minidom`'s attribute value escaping.
4
5 :meth:`xml.dom.minidom.Element.setAttribute` doesn't preform some
6 character escaping (see the `Python bug`_ and `XML specs`_).
7 Importing this module applies the suggested patch dynamically.
8
9 .. _Python bug: http://bugs.python.org/issue5752
10 .. _XML specs:
11   http://www.w3.org/TR/2000/WD-xml-c14n-20000119.html#charescaping
12 """
13
14 import xml.dom.minidom
15
16
17 def _write_data(writer, data, isAttrib=False):
18     "Writes datachars to writer."
19     if isAttrib:
20         data = data.replace("\r", "
").replace("\n", "
")
21         data = data.replace("\t", "	").replace('"', """)
22     writer.write(data)
23 xml.dom.minidom._write_data = _write_data
24
25 def writexml(self, writer, indent="", addindent="", newl=""):
26     # indent = current indentation
27     # addindent = indentation to add to higher levels
28     # newl = newline string
29     writer.write(indent+"<" + self.tagName)
30
31     attrs = self._get_attributes()
32     a_names = attrs.keys()
33     a_names.sort()
34
35     for a_name in a_names:
36         writer.write(" %s=\"" % a_name)
37         _write_data(writer, attrs[a_name].value, isAttrib=True)
38         writer.write("\"")
39     if self.childNodes:
40         writer.write(">%s"%(newl))
41         for node in self.childNodes:
42             node.writexml(writer,indent+addindent,addindent,newl)
43         writer.write("%s</%s>%s" % (indent,self.tagName,newl))
44     else:
45         writer.write("/>%s"%(newl))
46 # For an introduction to overriding instance methods, see
47 #   http://irrepupavel.com/documents/python/instancemethod/
48 instancemethod = type(xml.dom.minidom.Element.writexml)
49 xml.dom.minidom.Element.writexml = instancemethod(
50     writexml, None, xml.dom.minidom.Element)