]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
tools: add helper method for printing an XML document
authorDaniel P. Berrangé <berrange@redhat.com>
Thu, 16 Jun 2022 14:59:03 +0000 (15:59 +0100)
committerDaniel P. Berrangé <berrange@redhat.com>
Mon, 20 Jun 2022 09:40:34 +0000 (10:40 +0100)
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>

Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
tools/virsh-util.c
tools/virsh-util.h

index ef275a43694c1f8e7baa4d9b639566826ccfab20..8a20f627a1cc7db14323af611c1d5782b321cb93 100644 (file)
@@ -436,3 +436,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;
+}
index 4d4fe6c01eb9448cc222924ad46e58b3cc2801df..0f81a2771bc8f6892ff57ea23b7989bb8b6090d2 100644 (file)
@@ -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);