[RFCv2 04/46] util: Add some xml-helper-functions to cooperate with xmlgen

Shi Lei shi_lei at massclouds.com
Fri Sep 4 03:34:56 UTC 2020


1) virXMLChildNode and virXMLChildNodeSet
   Parse xml without using xmlXPathContext.

2) virXMLChildPropString
   Support to parse attribute by path.

3) virXMLFlag
   Convert opaque to flag.

Signed-off-by: Shi Lei <shi_lei at massclouds.com>
---
 src/libvirt_private.syms |   4 ++
 src/util/virxml.c        | 105 +++++++++++++++++++++++++++++++++++++++
 src/util/virxml.h        |   6 +++
 3 files changed, 115 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 5736a2d..191eab0 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -3505,7 +3505,11 @@ virVsockSetGuestCid;
 virParseScaledValue;
 virXMLCheckIllegalChars;
 virXMLChildElementCount;
+virXMLChildNode;
+virXMLChildNodeSet;
+virXMLChildPropString;
 virXMLExtractNamespaceXML;
+virXMLFlag;
 virXMLFormatElement;
 virXMLNodeContentString;
 virXMLNodeNameEqual;
diff --git a/src/util/virxml.c b/src/util/virxml.c
index 5315d4f..a7d9a2c 100644
--- a/src/util/virxml.c
+++ b/src/util/virxml.c
@@ -1481,3 +1481,108 @@ virParseScaledValue(const char *xpath,
     *val = bytes;
     return 1;
 }
+
+
+/**
+ * virXMLChildNode:
+ * @node: Parent XML dom node pointer
+ * @name: Name of the child element
+ *
+ * Convenience function to return the child element of a XML node.
+ *
+ * Returns the pointer of child element node or NULL in case of failure.
+ * If there are many nodes match condition, it only returns the first node.
+ */
+xmlNodePtr
+virXMLChildNode(xmlNodePtr node, const char *name)
+{
+    xmlNodePtr cur = node->children;
+    while (cur) {
+        if (cur->type == XML_ELEMENT_NODE && virXMLNodeNameEqual(cur, name))
+            return cur;
+        cur = cur->next;
+    }
+    return NULL;
+}
+
+
+/**
+ * virXMLChildPropString:
+ * @node: Parent XML dom node pointer
+ * @path: Path of the property (attribute) to get
+ *
+ * Convenience function to return copy of an attribute value by a path.
+ * Path consists of names of child elements and an attribute.
+ * The delimiter is '/'.
+ *
+ * E.g.: For <self><son><grandson name="..."></grandson></son></self>,
+ * the path is 'son/grandSon/name' to get attribute 'name'.
+ *
+ * Returns the property (attribute) value as string or NULL in case of failure.
+ * The caller is responsible for freeing the returned buffer.
+ */
+char *
+virXMLChildPropString(xmlNodePtr node, const char *path)
+{
+    char *next;
+    char *sep;
+    xmlNodePtr tnode = node;
+    g_autofree char *tmp = NULL;
+    tmp = g_strdup(path);
+
+    next = tmp;
+    while ((sep = strchr(next, '/'))) {
+        *sep = '\0';
+
+        if ((tnode = virXMLChildNode(tnode, next)) == NULL)
+            return NULL;
+
+        next = sep + 1;
+    }
+
+    return virXMLPropString(tnode, next);
+}
+
+
+/**
+ * virXMLChildNodeSet:
+ * @node: Parent XML dom node pointer
+ * @name: Name of the children element
+ * @list: the returned list of nodes (or NULL if only count matters)
+ *
+ * Convenience function to evaluate a set of children elements
+ *
+ * Returns the number of nodes found in which case @list is set (and
+ *         must be freed) or -1 if the evaluation failed.
+ */
+int
+virXMLChildNodeSet(xmlNodePtr node, const char *name, xmlNodePtr **list)
+{
+    size_t count = 0;
+    xmlNodePtr cur = node->children;
+
+    if (list != NULL)
+        *list = NULL;
+
+    while (cur) {
+        if (cur->type == XML_ELEMENT_NODE && virXMLNodeNameEqual(cur, name)) {
+            if (list != NULL) {
+                if (VIR_APPEND_ELEMENT_COPY(*list, count, cur) < 0)
+                    return -1;
+            } else {
+                count++;
+            }
+        }
+        cur = cur->next;
+    }
+    return count;
+}
+
+
+unsigned int
+virXMLFlag(void *opaque)
+{
+    if (opaque)
+        return *((unsigned int *) opaque);
+    return 0;
+}
diff --git a/src/util/virxml.h b/src/util/virxml.h
index 0301f15..85e8eed 100644
--- a/src/util/virxml.h
+++ b/src/util/virxml.h
@@ -79,6 +79,10 @@ char *     virXMLPropStringLimit(xmlNodePtr node,
 char *   virXMLNodeContentString(xmlNodePtr node);
 long     virXMLChildElementCount(xmlNodePtr node);
 
+xmlNodePtr virXMLChildNode(xmlNodePtr node, const char *name);
+int virXMLChildNodeSet(xmlNodePtr node, const char *name, xmlNodePtr **list);
+char * virXMLChildPropString(xmlNodePtr node, const char *path);
+
 /* Internal function; prefer the macros below.  */
 xmlDocPtr      virXMLParseHelper(int domcode,
                                  const char *filename,
@@ -279,3 +283,5 @@ int virParseScaledValue(const char *xpath,
                         unsigned long long scale,
                         unsigned long long max,
                         bool required);
+
+unsigned int virXMLFlag(void *opaque);
-- 
2.25.1





More information about the libvir-list mailing list