--- /dev/null
+# Copyright
+
+"""Dynamically patch :mod:`xml.dom.minidom`'s attribute value escaping.
+
+:meth:`xml.dom.minidom.Element.setAttribute` doesn't preform some
+character escaping (see the `Python bug`_ and `XML specs`_).
+Importing this module applies the suggested patch dynamically.
+
+.. _Python bug: http://bugs.python.org/issue5752
+.. _XML specs:
+ http://www.w3.org/TR/2000/WD-xml-c14n-20000119.html#charescaping
+"""
+
+import xml.dom.minidom
+
+
+def _write_data(writer, data, isAttrib=False):
+ "Writes datachars to writer."
+ if isAttrib:
+ data = data.replace("\r", "
").replace("\n", "
")
+ data = data.replace("\t", "	")
+ writer.write(data)
+xml.dom.minidom._write_data = _write_data
+
+def writexml(self, writer, indent="", addindent="", newl=""):
+ # indent = current indentation
+ # addindent = indentation to add to higher levels
+ # newl = newline string
+ writer.write(indent+"<" + self.tagName)
+
+ attrs = self._get_attributes()
+ a_names = attrs.keys()
+ a_names.sort()
+
+ for a_name in a_names:
+ writer.write(" %s=\"" % a_name)
+ _write_data(writer, attrs[a_name].value, isAttrib=True)
+ writer.write("\"")
+ if self.childNodes:
+ writer.write(">%s"%(newl))
+ for node in self.childNodes:
+ node.writexml(writer,indent+addindent,addindent,newl)
+ writer.write("%s</%s>%s" % (indent,self.tagName,newl))
+ else:
+ writer.write("/>%s"%(newl))
+# For an introduction to overriding instance methods, see
+# http://irrepupavel.com/documents/python/instancemethod/
+instancemethod = type(xml.dom.minidom.Element.writexml)
+xml.dom.minidom.Element.writexml = instancemethod(
+ writexml, None, xml.dom.minidom.Element)
import xml.dom.minidom
from . import curve as curve
+from .compat import minidom as minidom # dynamically patch xml.sax.minidom
class NoteIndexList (list):
>>> c.info['note'] = 'The first curve'
>>> p.append(c)
>>> c = curve.Curve(os.path.join(root_path, 'to', 'curve', 'two'))
- >>> c.info['note'] = 'The second curve'
+ >>> c.info['note'] = 'The second curve\\nwith endlines'
>>> p.append(c)
>>> print p.flatten() # doctest: +NORMALIZE_WHITESPACE +REPORT_UDIFF
<?xml version="1.0" encoding="utf-8"?>
<playlist index="0" note="An example playlist" version="0.1">
- <curve note="The first curve" path="curve/one"/>
- <curve note="The second curve" path="curve/two"/>
+ <curve note="The first curve" path="curve/one"/>
+ <curve note="The second curve
with endlines" path="curve/two"/>
</playlist>
<BLANKLINE>
>>> print p.flatten(absolute_paths=True) # doctest: +NORMALIZE_WHITESPACE +REPORT_UDIFF
<?xml version="1.0" encoding="utf-8"?>
<playlist index="0" note="An example playlist" version="0.1">
- <curve note="The first curve" path="/path/to/curve/one"/>
- <curve note="The second curve" path="/path/to/curve/two"/>
+ <curve note="The first curve" path="/path/to/curve/one"/>
+ <curve note="The second curve
with endlines" path="/path/to/curve/two"/>
</playlist>
<BLANKLINE>
"""
for key,value in curve.info.items():
if key in self._ignored_keys:
continue
- curve_element.setAttribute(key, str(value))
+ curve_element.setAttribute(key,str(value))
string = doc.toprettyxml(encoding='utf-8')
root.unlink() # break circular references for garbage collection
return string
>>> string = '''<?xml version="1.0" encoding="utf-8"?>
... <playlist index="1" note="An example playlist" version="0.1">
... <curve note="The first curve" path="../curve/one"/>
- ... <curve note="The second curve" path="../curve/two"/>
+ ... <curve note="The second curve
with endlines" path="../curve/two"/>
... </playlist>
... '''
>>> p = FilePlaylist(drivers=[],
... print curve.path
path/to/curve/one
path/to/curve/two
+ >>> p[-1].info['note']
+ u'The second curve\\nwith endlines'
"""
doc = xml.dom.minidom.parseString(string)
self._from_xml_doc(doc, identify=identify)