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(a)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