diff -r 16accac4b2f6 Lib/xml/etree/ElementTree.py --- a/Lib/xml/etree/ElementTree.py Wed Dec 16 05:04:29 2015 +0000 +++ b/Lib/xml/etree/ElementTree.py Wed Dec 16 13:13:08 2015 +0200 @@ -895,33 +895,31 @@ def _namespaces(elem, default_namespace= def _serialize_xml(write, elem, qnames, namespaces, short_empty_elements, **kwargs): - tag = elem.tag - text = elem.text - if tag is Comment: - write("" % text) - elif tag is ProcessingInstruction: - write("" % text) - else: - tag = qnames[tag] - if tag is None: + def recurse(elem): + tag = elem.tag + text = elem.text + if tag is Comment: + write("" % text) + elif tag is ProcessingInstruction: + write("" % text) + elif tag is None: if text: write(_escape_cdata(text)) for e in elem: - _serialize_xml(write, e, qnames, None, - short_empty_elements=short_empty_elements) + recurse(e) else: + tag = qnames[tag] write("<" + tag) items = list(elem.items()) - if items or namespaces: - if namespaces: - for v, k in sorted(namespaces.items(), - key=lambda x: x[1]): # sort on prefix - if k: - k = ":" + k - write(" xmlns%s=\"%s\"" % ( - k, - _escape_attrib(v) - )) + nonlocal namespaces + if namespaces: + for v, k in sorted(namespaces.items(), + key=lambda x: x[1]): # sort on prefix + if k: + k = ":" + k + write(' xmlns%s="%s"' % (k, _escape_attrib(v))) + namespaces = None + if items: for k, v in sorted(items): # lexical order if isinstance(k, QName): k = k.text @@ -929,19 +927,20 @@ def _serialize_xml(write, elem, qnames, v = qnames[v.text] else: v = _escape_attrib(v) - write(" %s=\"%s\"" % (qnames[k], v)) + write(' %s="%s"' % (qnames[k], v)) if text or len(elem) or not short_empty_elements: write(">") if text: write(_escape_cdata(text)) for e in elem: - _serialize_xml(write, e, qnames, None, - short_empty_elements=short_empty_elements) + recurse(e) write("") else: write(" />") - if elem.tail: - write(_escape_cdata(elem.tail)) + if elem.tail: + write(_escape_cdata(elem.tail)) + + return recurse(elem) HTML_EMPTY = ("area", "base", "basefont", "br", "col", "frame", "hr", "img", "input", "isindex", "link", "meta", "param") @@ -952,32 +951,31 @@ except NameError: pass def _serialize_html(write, elem, qnames, namespaces, **kwargs): - tag = elem.tag - text = elem.text - if tag is Comment: - write("" % _escape_cdata(text)) - elif tag is ProcessingInstruction: - write("" % _escape_cdata(text)) - else: - tag = qnames[tag] - if tag is None: + def recurse(elem): + tag = elem.tag + text = elem.text + if tag is Comment: + write("" % _escape_cdata(text)) + elif tag is ProcessingInstruction: + write("" % _escape_cdata(text)) + elif tag is None: if text: write(_escape_cdata(text)) for e in elem: - _serialize_html(write, e, qnames, None) + recurse(e) else: + tag = qnames[tag] write("<" + tag) items = list(elem.items()) - if items or namespaces: - if namespaces: - for v, k in sorted(namespaces.items(), - key=lambda x: x[1]): # sort on prefix - if k: - k = ":" + k - write(" xmlns%s=\"%s\"" % ( - k, - _escape_attrib(v) - )) + nonlocal namespaces + if namespaces: + for v, k in sorted(namespaces.items(), + key=lambda x: x[1]): # sort on prefix + if k: + k = ":" + k + write(' xmlns%s="%s"' % (k, _escape_attrib_html(v))) + namespaces = None + if items: for k, v in sorted(items): # lexical order if isinstance(k, QName): k = k.text @@ -986,7 +984,7 @@ def _serialize_html(write, elem, qnames, else: v = _escape_attrib_html(v) # FIXME: handle boolean attributes - write(" %s=\"%s\"" % (qnames[k], v)) + write(' %s="%s"' % (qnames[k], v)) write(">") ltag = tag.lower() if text: @@ -995,11 +993,13 @@ def _serialize_html(write, elem, qnames, else: write(_escape_cdata(text)) for e in elem: - _serialize_html(write, e, qnames, None) + recurse(e) if ltag not in HTML_EMPTY: write("") - if elem.tail: - write(_escape_cdata(elem.tail)) + if elem.tail: + write(_escape_cdata(elem.tail)) + + return recurse(elem) def _serialize_text(write, elem): for part in elem.itertext():