mirror of
https://github.com/httpie/cli.git
synced 2024-11-28 18:53:21 +01:00
Don't inconsistently add XML declarations (#1227)
This commit is contained in:
parent
4f7f59b990
commit
3db1cdba4c
@ -15,6 +15,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
|||||||
- Added support for basic JSON types on `--form`/`--multipart` when using JSON only operators (`:=`/`:=@`). ([#1212](https://github.com/httpie/httpie/issues/1212))
|
- Added support for basic JSON types on `--form`/`--multipart` when using JSON only operators (`:=`/`:=@`). ([#1212](https://github.com/httpie/httpie/issues/1212))
|
||||||
- Added support for automatically enabling `--stream` when `Content-Type` is `text/event-stream`. ([#376](https://github.com/httpie/httpie/issues/376))
|
- Added support for automatically enabling `--stream` when `Content-Type` is `text/event-stream`. ([#376](https://github.com/httpie/httpie/issues/376))
|
||||||
- Broken plugins will no longer crash the whole application. ([#1204](https://github.com/httpie/httpie/issues/1204))
|
- Broken plugins will no longer crash the whole application. ([#1204](https://github.com/httpie/httpie/issues/1204))
|
||||||
|
- Fixed auto addition of XML declaration to every formatted XML response. ([#1156](https://github.com/httpie/httpie/issues/1156))
|
||||||
|
|
||||||
## [2.6.0](https://github.com/httpie/httpie/compare/2.5.0...2.6.0) (2021-10-14)
|
## [2.6.0](https://github.com/httpie/httpie/compare/2.5.0...2.6.0) (2021-10-14)
|
||||||
|
|
||||||
|
@ -1747,7 +1747,9 @@ Formatting has the following effects:
|
|||||||
to the characters they represent.
|
to the characters they represent.
|
||||||
- XML and XHTML data is indented.
|
- XML and XHTML data is indented.
|
||||||
|
|
||||||
You can further control the applied formatting via the more granular [format options](#format-options).
|
Please note that sometimes there might be changes made by formatters on the actual response body (e.g
|
||||||
|
collapsing empty tags on XML) but the end result will always be semantically indistinguishable. Some of
|
||||||
|
these formatting changes can be configured more granularly through [format options](#format-options).
|
||||||
|
|
||||||
### Format options
|
### Format options
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import sys
|
|
||||||
from typing import TYPE_CHECKING, Optional
|
from typing import TYPE_CHECKING, Optional
|
||||||
|
|
||||||
from ...encoding import UTF8
|
from ...encoding import UTF8
|
||||||
@ -8,27 +7,47 @@ if TYPE_CHECKING:
|
|||||||
from xml.dom.minidom import Document
|
from xml.dom.minidom import Document
|
||||||
|
|
||||||
|
|
||||||
|
XML_DECLARATION_OPEN = '<?xml'
|
||||||
|
XML_DECLARATION_CLOSE = '?>'
|
||||||
|
|
||||||
|
|
||||||
def parse_xml(data: str) -> 'Document':
|
def parse_xml(data: str) -> 'Document':
|
||||||
"""Parse given XML `data` string into an appropriate :class:`~xml.dom.minidom.Document` object."""
|
"""Parse given XML `data` string into an appropriate :class:`~xml.dom.minidom.Document` object."""
|
||||||
from defusedxml.minidom import parseString
|
from defusedxml.minidom import parseString
|
||||||
return parseString(data)
|
return parseString(data)
|
||||||
|
|
||||||
|
|
||||||
|
def parse_declaration(raw_body: str) -> Optional[str]:
|
||||||
|
body = raw_body.strip()
|
||||||
|
# XMLDecl ::= '<?xml' DECL_CONTENT '?>'
|
||||||
|
if body.startswith(XML_DECLARATION_OPEN):
|
||||||
|
end = body.find(XML_DECLARATION_CLOSE)
|
||||||
|
if end != -1:
|
||||||
|
return body[:end + len(XML_DECLARATION_CLOSE)]
|
||||||
|
|
||||||
|
|
||||||
def pretty_xml(document: 'Document',
|
def pretty_xml(document: 'Document',
|
||||||
|
declaration: Optional[str] = None,
|
||||||
encoding: Optional[str] = UTF8,
|
encoding: Optional[str] = UTF8,
|
||||||
indent: int = 2,
|
indent: int = 2) -> str:
|
||||||
standalone: Optional[bool] = None) -> str:
|
|
||||||
"""Render the given :class:`~xml.dom.minidom.Document` `document` into a prettified string."""
|
"""Render the given :class:`~xml.dom.minidom.Document` `document` into a prettified string."""
|
||||||
kwargs = {
|
kwargs = {
|
||||||
'encoding': encoding or UTF8,
|
'encoding': encoding or UTF8,
|
||||||
'indent': ' ' * indent,
|
'indent': ' ' * indent,
|
||||||
}
|
}
|
||||||
if standalone is not None and sys.version_info >= (3, 9):
|
|
||||||
kwargs['standalone'] = standalone
|
|
||||||
body = document.toprettyxml(**kwargs).decode(kwargs['encoding'])
|
body = document.toprettyxml(**kwargs).decode(kwargs['encoding'])
|
||||||
|
|
||||||
# Remove blank lines automatically added by `toprettyxml()`.
|
# Remove blank lines automatically added by `toprettyxml()`.
|
||||||
return '\n'.join(line for line in body.splitlines() if line.strip())
|
lines = [line for line in body.splitlines() if line.strip()]
|
||||||
|
|
||||||
|
# xml.dom automatically adds the declaration, even if
|
||||||
|
# it is not present in the actual body. Remove it.
|
||||||
|
if len(lines) >= 1 and parse_declaration(lines[0]):
|
||||||
|
lines.pop(0)
|
||||||
|
if declaration:
|
||||||
|
lines.insert(0, declaration)
|
||||||
|
|
||||||
|
return '\n'.join(lines)
|
||||||
|
|
||||||
|
|
||||||
class XMLFormatter(FormatterPlugin):
|
class XMLFormatter(FormatterPlugin):
|
||||||
@ -44,6 +63,7 @@ class XMLFormatter(FormatterPlugin):
|
|||||||
from xml.parsers.expat import ExpatError
|
from xml.parsers.expat import ExpatError
|
||||||
from defusedxml.common import DefusedXmlException
|
from defusedxml.common import DefusedXmlException
|
||||||
|
|
||||||
|
declaration = parse_declaration(body)
|
||||||
try:
|
try:
|
||||||
parsed_body = parse_xml(body)
|
parsed_body = parse_xml(body)
|
||||||
except ExpatError:
|
except ExpatError:
|
||||||
@ -54,6 +74,6 @@ class XMLFormatter(FormatterPlugin):
|
|||||||
body = pretty_xml(parsed_body,
|
body = pretty_xml(parsed_body,
|
||||||
encoding=parsed_body.encoding,
|
encoding=parsed_body.encoding,
|
||||||
indent=self.format_options['xml']['indent'],
|
indent=self.format_options['xml']['indent'],
|
||||||
standalone=parsed_body.standalone)
|
declaration=declaration)
|
||||||
|
|
||||||
return body
|
return body
|
||||||
|
3
tests/fixtures/xmldata/valid/custom-header.xml
vendored
Normal file
3
tests/fixtures/xmldata/valid/custom-header.xml
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?><!-- comment -->
|
||||||
|
<root><element key="value">text</element><element>text</element>tail<empty-element/></root>
|
||||||
|
<!-- comment -->
|
9
tests/fixtures/xmldata/valid/custom-header_formatted.xml
vendored
Normal file
9
tests/fixtures/xmldata/valid/custom-header_formatted.xml
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- comment -->
|
||||||
|
<root>
|
||||||
|
<element key="value">text</element>
|
||||||
|
<element>text</element>
|
||||||
|
tail
|
||||||
|
<empty-element/>
|
||||||
|
</root>
|
||||||
|
|
@ -1,4 +1,3 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<?pi data?>
|
<?pi data?>
|
||||||
<!-- comment -->
|
<!-- comment -->
|
||||||
<root xmlns="namespace">
|
<root xmlns="namespace">
|
||||||
|
1
tests/fixtures/xmldata/valid/simple-single-tag_formatted.xml
vendored
Normal file
1
tests/fixtures/xmldata/valid/simple-single-tag_formatted.xml
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
<a/>
|
1
tests/fixtures/xmldata/valid/simple-single-tag_raw.xml
vendored
Normal file
1
tests/fixtures/xmldata/valid/simple-single-tag_raw.xml
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
<a></a>
|
@ -1,4 +1,3 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- comment -->
|
<!-- comment -->
|
||||||
<root>
|
<root>
|
||||||
<element key="value">text</element>
|
<element key="value">text</element>
|
||||||
|
Loading…
Reference in New Issue
Block a user