replace XML processor with ElementTree with custom indentation

This commit is contained in:
Rav Chandra 2013-10-16 13:07:53 +13:00
parent bcdf194bae
commit bee10e5eed

View File

@ -2,7 +2,7 @@
""" """
import json import json
import xml.dom.minidom from xml.etree import ElementTree
from functools import partial from functools import partial
from itertools import chain from itertools import chain
@ -406,15 +406,33 @@ class XMLProcessor(BaseProcessor):
"""XML body processor.""" """XML body processor."""
# TODO: tests # TODO: tests
# in-place prettyprint formatter
# c.f. http://effbot.org/zone/element-lib.htm#prettyprint
@staticmethod
def indent(elem, indent_text=' ' * DEFAULT_INDENT):
def _indent(elem, level=0):
i = "\n" + level * indent_text
if len(elem):
if not elem.text or not elem.text.strip():
elem.text = i + indent_text
if not elem.tail or not elem.tail.strip():
elem.tail = i
for elem in elem:
_indent(elem, level + 1)
if not elem.tail or not elem.tail.strip():
elem.tail = i
else:
if level and (not elem.tail or not elem.tail.strip()):
elem.tail = i
return _indent(elem)
def process_body(self, content, content_type, subtype, encoding): def process_body(self, content, content_type, subtype, encoding):
if subtype == 'xml': if subtype == 'xml':
try: try:
# Pretty print the XML; pre-process content into clean string root = ElementTree.fromstring(content.encode(encoding))
raw_string = ''.join( self.indent(root)
(x.strip() for x in content.encode(encoding).split('\n'))) content = ElementTree.tostring(root)
doc = xml.dom.minidom.parseString(raw_string) except ElementTree.ParseError:
content = doc.toprettyxml(indent=' ' * DEFAULT_INDENT)
except xml.parsers.expat.ExpatError:
# Ignore invalid XML errors (skips attempting to pretty print) # Ignore invalid XML errors (skips attempting to pretty print)
pass pass
return content return content