diff --git a/src/util/virxml.c b/src/util/virxml.c
index 027cdb97b9..6d0c8f0311 100644
--- a/src/util/virxml.c
+++ b/src/util/virxml.c
@@ -1129,14 +1129,15 @@ virXMLParseHelper(int domcode,
const char *rootelement,
xmlXPathContextPtr *ctxt,
const char *schemafile,
- bool validate)
+ bool validate,
+ bool keepindent)
{
struct virParserData private;
g_autoptr(xmlParserCtxt) pctxt = NULL;
g_autoptr(xmlDoc) xml = NULL;
xmlNodePtr rootnode;
const char *docname;
- const int parseFlags = XML_PARSE_NONET | XML_PARSE_NOWARNING;
+ int parseFlags = XML_PARSE_NONET | XML_PARSE_NOWARNING;
if (filename)
docname = filename;
@@ -1154,6 +1155,10 @@ virXMLParseHelper(int domcode,
pctxt->_private = &private;
pctxt->sax->error = catchXMLError;
+ if (keepindent) {
+ parseFlags |= XML_PARSE_NOBLANKS;
+ }
+
if (filename) {
xml = xmlCtxtReadFile(pctxt, filename, NULL, parseFlags);
} else {
diff --git a/src/util/virxml.h b/src/util/virxml.h
index 7af47437bd..03a85bfb25 100644
--- a/src/util/virxml.h
+++ b/src/util/virxml.h
@@ -199,7 +199,8 @@ virXMLParseHelper(int domcode,
const char *rootelement,
xmlXPathContextPtr *ctxt,
const char *schemafile,
- bool validate);
+ bool validate,
+ bool keepindent);
const char *
virXMLPickShellSafeComment(const char *str1,
@@ -219,7 +220,17 @@ virXMLPickShellSafeComment(const char *str1,
* Return the parsed document object, or NULL on failure.
*/
#define virXMLParse(filename, xmlStr, url, rootelement, ctxt, schemafile, validate) \
- virXMLParseHelper(VIR_FROM_THIS, filename, xmlStr, url, rootelement, ctxt, schemafile, validate)
+ virXMLParseHelper(VIR_FROM_THIS, filename, xmlStr, url, rootelement, ctxt, schemafile, validate, false)
+
+/**
+ * virXMLParseWithIndent:
+ *
+ * Just like virXMLParse, except indentation is preserved. Should be used when
+ * facing an user provided XML which may be formatted back and keeping verbatim
+ * spacing is necessary (e.g. due to ).
+ */
+#define virXMLParseWithIndent(filename, xmlStr, url, rootelement, ctxt, schemafile, validate) \
+ virXMLParseHelper(VIR_FROM_THIS, filename, xmlStr, url, rootelement, ctxt, schemafile, validate, true)
/**
* virXMLParseStringCtxt:
@@ -233,7 +244,17 @@ virXMLPickShellSafeComment(const char *str1,
* Return the parsed document object, or NULL on failure.
*/
#define virXMLParseStringCtxt(xmlStr, url, pctxt) \
- virXMLParseHelper(VIR_FROM_THIS, NULL, xmlStr, url, NULL, pctxt, NULL, false)
+ virXMLParseHelper(VIR_FROM_THIS, NULL, xmlStr, url, NULL, pctxt, NULL, false, false)
+
+/**
+ * virXMLParseStringCtxtWithIndent:
+ *
+ * Just like virXMLParseStringCtxt, except indentation is preserved. Should be
+ * used when facing an user provided XML which may be formatted back and
+ * keeping verbatim spacing is necessary (e.g. due to ).
+ */
+#define virXMLParseStringCtxtWithIndent(xmlStr, url, pctxt) \
+ virXMLParseHelper(VIR_FROM_THIS, NULL, xmlStr, url, NULL, pctxt, NULL, false, true)
/**
* virXMLParseFileCtxt:
@@ -246,7 +267,7 @@ virXMLPickShellSafeComment(const char *str1,
* Return the parsed document object, or NULL on failure.
*/
#define virXMLParseFileCtxt(filename, pctxt) \
- virXMLParseHelper(VIR_FROM_THIS, filename, NULL, NULL, NULL, pctxt, NULL, false)
+ virXMLParseHelper(VIR_FROM_THIS, filename, NULL, NULL, NULL, pctxt, NULL, false, false)
int
virXMLSaveFile(const char *path,