From bee10e5eed5a01bfca7f30ff8f13215add31cde3 Mon Sep 17 00:00:00 2001 From: Rav Chandra Date: Wed, 16 Oct 2013 13:07:53 +1300 Subject: [PATCH] replace XML processor with ElementTree with custom indentation --- httpie/output.py | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/httpie/output.py b/httpie/output.py index 56bc69d6..ee368435 100644 --- a/httpie/output.py +++ b/httpie/output.py @@ -2,7 +2,7 @@ """ import json -import xml.dom.minidom +from xml.etree import ElementTree from functools import partial from itertools import chain @@ -406,15 +406,33 @@ class XMLProcessor(BaseProcessor): """XML body processor.""" # 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): if subtype == 'xml': try: - # Pretty print the XML; pre-process content into clean string - raw_string = ''.join( - (x.strip() for x in content.encode(encoding).split('\n'))) - doc = xml.dom.minidom.parseString(raw_string) - content = doc.toprettyxml(indent=' ' * DEFAULT_INDENT) - except xml.parsers.expat.ExpatError: + root = ElementTree.fromstring(content.encode(encoding)) + self.indent(root) + content = ElementTree.tostring(root) + except ElementTree.ParseError: # Ignore invalid XML errors (skips attempting to pretty print) pass return content