diff options
Diffstat (limited to 'src/backend/utils/adt/xml.c')
-rw-r--r-- | src/backend/utils/adt/xml.c | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/src/backend/utils/adt/xml.c b/src/backend/utils/adt/xml.c index 447e72b21eb..1a07876cd59 100644 --- a/src/backend/utils/adt/xml.c +++ b/src/backend/utils/adt/xml.c @@ -677,8 +677,14 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent) } #ifdef USE_LIBXML - /* Parse the input according to the xmloption */ - doc = xml_parse(data, xmloption_arg, true, GetDatabaseEncoding(), + + /* + * Parse the input according to the xmloption. + * + * preserve_whitespace is set to false in case we are indenting, otherwise + * libxml2 will fail to indent elements that have whitespace between them. + */ + doc = xml_parse(data, xmloption_arg, !indent, GetDatabaseEncoding(), &parsed_xmloptiontype, &content_nodes, (Node *) &escontext); if (doc == NULL || escontext.error_occurred) @@ -802,7 +808,22 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent) "could not close xmlSaveCtxtPtr"); } - result = (text *) xmlBuffer_to_xmltype(buf); + /* + * xmlDocContentDumpOutput may add a trailing newline, so remove that. + */ + if (xmloption_arg == XMLOPTION_DOCUMENT) + { + const char *str = (const char *) xmlBufferContent(buf); + int len = xmlBufferLength(buf); + + while (len > 0 && (str[len - 1] == '\n' || + str[len - 1] == '\r')) + len--; + + result = cstring_to_text_with_len(str, len); + } + else + result = (text *) xmlBuffer_to_xmltype(buf); } PG_CATCH(); { |