[libvirt PATCH 1/2] tools: add helper method for printing an XML document

Daniel P. Berrangé berrange at redhat.com
Thu Jun 16 15:36:52 UTC 2022


The trivial case of fully printing an XML document is boring, but
this helper does more by allowing an XPath expression to be given.
It will then print just the subset of nodes which match the
expression. It either print each match as a standalone XML doc
or can put them into one new XML doc wrapped woith <nodes>...</nodes>

Signed-off-by: Daniel P. Berrangé <berrange at redhat.com>
---
 tools/virsh-util.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++
 tools/virsh-util.h |  7 ++++++
 2 files changed, 66 insertions(+)

diff --git a/tools/virsh-util.c b/tools/virsh-util.c
index dc6ed7a86d..8b06091be8 100644
--- a/tools/virsh-util.c
+++ b/tools/virsh-util.c
@@ -437,3 +437,62 @@ virshDomainBlockJobToString(int type)
     const char *str = virshDomainBlockJobTypeToString(type);
     return str ? _(str) : _("Unknown job");
 }
+
+bool
+virshDumpXML(vshControl *ctl,
+             const char *xml,
+             const char *url,
+             const char *xpath,
+             bool wrap)
+{
+    g_autoptr(xmlDoc) doc = NULL;
+    g_autoptr(xmlXPathContext) ctxt = NULL;
+    g_autofree xmlNodePtr *nodes = NULL;
+    int nnodes = 0;
+    size_t i;
+    int oldblanks;
+
+    if (xpath == NULL) {
+        vshPrint(ctl, "%s", xml);
+        return true;
+    }
+
+    oldblanks = xmlKeepBlanksDefault(0);
+    doc = virXMLParseString(xml, url);
+    xmlKeepBlanksDefault(oldblanks);
+    if (!doc)
+        return false;
+
+    if (!(ctxt = virXMLXPathContextNew(doc)))
+        return false;
+
+    if ((nnodes = virXPathNodeSet(xpath, ctxt, &nodes)) < 0) {
+        return false;
+    }
+
+    if (wrap) {
+        g_autoptr(xmlDoc) newdoc = xmlNewDoc((xmlChar *)"1.0");
+        xmlNodePtr newroot = xmlNewNode(NULL, (xmlChar *)"nodes");
+        g_autofree char *xmlbit = NULL;
+
+        xmlDocSetRootElement(newdoc, newroot);
+
+        for (i = 0; i < nnodes; i++) {
+            g_autoptr(xmlNode) copy = xmlDocCopyNode(nodes[i], newdoc, 1);
+            if (!xmlAddChild(newroot, copy))
+                return false;
+
+            copy = NULL;
+        }
+
+        xmlbit = virXMLNodeToString(doc, newroot);
+        vshPrint(ctl, "%s\n", xmlbit);
+    } else {
+        for (i = 0; i < nnodes; i++) {
+            g_autofree char *xmlbit = virXMLNodeToString(doc, nodes[i]);
+            vshPrint(ctl, "%s\n", xmlbit);
+        }
+    }
+
+    return true;
+}
diff --git a/tools/virsh-util.h b/tools/virsh-util.h
index 4d4fe6c01e..0f81a2771b 100644
--- a/tools/virsh-util.h
+++ b/tools/virsh-util.h
@@ -156,3 +156,10 @@ VIR_ENUM_DECL(virshDomainBlockJob);
 
 const char *
 virshDomainBlockJobToString(int type);
+
+bool
+virshDumpXML(vshControl *ctl,
+             const char *xml,
+             const char *url,
+             const char *xpath,
+             bool wrap);
-- 
2.36.1



More information about the libvir-list mailing list