80a318
From 6371a0d85b6febd8e034eeec02d70c551535ad5b Mon Sep 17 00:00:00 2001
80a318
From: Michal Privoznik <mprivozn@redhat.com>
80a318
Date: Tue, 21 Nov 2023 10:39:58 +0100
80a318
Subject: [PATCH 6/7] virxml: Introduce parsing APIs that keep indentation
80a318
MIME-Version: 1.0
80a318
Content-Type: text/plain; charset=UTF-8
80a318
Content-Transfer-Encoding: 8bit
80a318
80a318
When parsing an XML it may be important to keep indentation to
80a318
produce a better looking result when formatting the XML back.
80a318
Just look at all those xmlKeepBlanksDefault() calls just before
80a318
virXMLParse() is called.
80a318
80a318
Anyway, as of libxml2 commit v2.12.0~108 xmlKeepBlanksDefault()
80a318
is deprecated. Therefore, introduce virXMLParse...WithIndent()
80a318
variants which would do exactly xmlKeepBlanksDefault() did but
80a318
with non-deprecated APIs.
80a318
80a318
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
80a318
Reviewed-by: Ján Tomko <jtomko@redhat.com>
80a318
(cherry picked from commit 69958ba3102810bb4f90a91d2f6d9032e1a1da2d)
80a318
---
80a318
 src/util/virxml.c |  9 +++++++--
80a318
 src/util/virxml.h | 29 +++++++++++++++++++++++++----
80a318
 2 files changed, 32 insertions(+), 6 deletions(-)
80a318
80a318
diff --git a/src/util/virxml.c b/src/util/virxml.c
80a318
index 027cdb97b9..6d0c8f0311 100644
80a318
--- a/src/util/virxml.c
80a318
+++ b/src/util/virxml.c
80a318
@@ -1129,14 +1129,15 @@ virXMLParseHelper(int domcode,
80a318
                   const char *rootelement,
80a318
                   xmlXPathContextPtr *ctxt,
80a318
                   const char *schemafile,
80a318
-                  bool validate)
80a318
+                  bool validate,
80a318
+                  bool keepindent)
80a318
 {
80a318
     struct virParserData private;
80a318
     g_autoptr(xmlParserCtxt) pctxt = NULL;
80a318
     g_autoptr(xmlDoc) xml = NULL;
80a318
     xmlNodePtr rootnode;
80a318
     const char *docname;
80a318
-    const int parseFlags = XML_PARSE_NONET | XML_PARSE_NOWARNING;
80a318
+    int parseFlags = XML_PARSE_NONET | XML_PARSE_NOWARNING;
80a318
 
80a318
     if (filename)
80a318
         docname = filename;
80a318
@@ -1154,6 +1155,10 @@ virXMLParseHelper(int domcode,
80a318
     pctxt->_private = &private;
80a318
     pctxt->sax->error = catchXMLError;
80a318
 
80a318
+    if (keepindent) {
80a318
+        parseFlags |= XML_PARSE_NOBLANKS;
80a318
+    }
80a318
+
80a318
     if (filename) {
80a318
         xml = xmlCtxtReadFile(pctxt, filename, NULL, parseFlags);
80a318
     } else {
80a318
diff --git a/src/util/virxml.h b/src/util/virxml.h
80a318
index 7af47437bd..03a85bfb25 100644
80a318
--- a/src/util/virxml.h
80a318
+++ b/src/util/virxml.h
80a318
@@ -199,7 +199,8 @@ virXMLParseHelper(int domcode,
80a318
                   const char *rootelement,
80a318
                   xmlXPathContextPtr *ctxt,
80a318
                   const char *schemafile,
80a318
-                  bool validate);
80a318
+                  bool validate,
80a318
+                  bool keepindent);
80a318
 
80a318
 const char *
80a318
 virXMLPickShellSafeComment(const char *str1,
80a318
@@ -219,7 +220,17 @@ virXMLPickShellSafeComment(const char *str1,
80a318
  * Return the parsed document object, or NULL on failure.
80a318
  */
80a318
 #define virXMLParse(filename, xmlStr, url, rootelement, ctxt, schemafile, validate) \
80a318
-    virXMLParseHelper(VIR_FROM_THIS, filename, xmlStr, url, rootelement, ctxt, schemafile, validate)
80a318
+    virXMLParseHelper(VIR_FROM_THIS, filename, xmlStr, url, rootelement, ctxt, schemafile, validate, false)
80a318
+
80a318
+/**
80a318
+ * virXMLParseWithIndent:
80a318
+ *
80a318
+ * Just like virXMLParse, except indentation is preserved. Should be used when
80a318
+ * facing an user provided XML which may be formatted back and keeping verbatim
80a318
+ * spacing is necessary (e.g. due to <metadata/>).
80a318
+ */
80a318
+#define virXMLParseWithIndent(filename, xmlStr, url, rootelement, ctxt, schemafile, validate) \
80a318
+    virXMLParseHelper(VIR_FROM_THIS, filename, xmlStr, url, rootelement, ctxt, schemafile, validate, true)
80a318
 
80a318
 /**
80a318
  * virXMLParseStringCtxt:
80a318
@@ -233,7 +244,17 @@ virXMLPickShellSafeComment(const char *str1,
80a318
  * Return the parsed document object, or NULL on failure.
80a318
  */
80a318
 #define virXMLParseStringCtxt(xmlStr, url, pctxt) \
80a318
-    virXMLParseHelper(VIR_FROM_THIS, NULL, xmlStr, url, NULL, pctxt, NULL, false)
80a318
+    virXMLParseHelper(VIR_FROM_THIS, NULL, xmlStr, url, NULL, pctxt, NULL, false, false)
80a318
+
80a318
+/**
80a318
+ * virXMLParseStringCtxtWithIndent:
80a318
+ *
80a318
+ * Just like virXMLParseStringCtxt, except indentation is preserved.  Should be
80a318
+ * used when facing an user provided XML which may be formatted back and
80a318
+ * keeping verbatim spacing is necessary (e.g. due to <metadata/>).
80a318
+ */
80a318
+#define virXMLParseStringCtxtWithIndent(xmlStr, url, pctxt) \
80a318
+    virXMLParseHelper(VIR_FROM_THIS, NULL, xmlStr, url, NULL, pctxt, NULL, false, true)
80a318
 
80a318
 /**
80a318
  * virXMLParseFileCtxt:
80a318
@@ -246,7 +267,7 @@ virXMLPickShellSafeComment(const char *str1,
80a318
  * Return the parsed document object, or NULL on failure.
80a318
  */
80a318
 #define virXMLParseFileCtxt(filename, pctxt) \
80a318
-    virXMLParseHelper(VIR_FROM_THIS, filename, NULL, NULL, NULL, pctxt, NULL, false)
80a318
+    virXMLParseHelper(VIR_FROM_THIS, filename, NULL, NULL, NULL, pctxt, NULL, false, false)
80a318
 
80a318
 int
80a318
 virXMLSaveFile(const char *path,
80a318
-- 
80a318
2.43.0
80a318