summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorDaniel P. Berrangé <berrange@redhat.com>2022-06-16 15:59:03 +0100
committerDaniel P. Berrangé <berrange@redhat.com>2022-06-20 10:40:34 +0100
commit8615c19b5d8650e0ef5cfb2ab41cee3b4d433bbb (patch)
tree16ec2e8eebad3b0e2782438854df8f659eb762f3 /tools
parent812edc95a36b997d674ce4f3a56f4fd01f31904e (diff)
downloadlibvirt-8615c19b5d8650e0ef5cfb2ab41cee3b4d433bbb.tar.gz
tools: add helper method for printing an XML document
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>
Diffstat (limited to 'tools')
-rw-r--r--tools/virsh-util.c59
-rw-r--r--tools/virsh-util.h7
2 files changed, 66 insertions, 0 deletions
diff --git a/tools/virsh-util.c b/tools/virsh-util.c
index ef275a4369..8a20f627a1 100644
--- a/tools/virsh-util.c
+++ b/tools/virsh-util.c
@@ -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;
+}
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);