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@xxxxxxxxxxxxxx> --- 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