* Added new function xml_child_index_each() to iterate over the children of an XML node according to the order defined by an explicit index variable.

This commit is contained in:
Olof hagsand 2020-05-20 15:21:59 +02:00
parent 1a1aa58249
commit 6629f3d780
3 changed files with 63 additions and 2 deletions

View file

@ -25,6 +25,10 @@
## 4.6.0
Expected: July 2020
### Minor changes
* Added new function `xml_child_index_each()` to iterate over the children of an XML node according to the order defined by an explicit index variable. This is a complement to `xml_child_each()` which iterates using the default order.
## 4.5.0
12 May 2020

View file

@ -249,6 +249,8 @@ int xml_search_index_p(cxobj *x);
int xml_search_vector_get(cxobj *x, char *name, clixon_xvec **xvec);
int xml_search_child_insert(cxobj *xp, cxobj *x);
int xml_search_child_rm(cxobj *xp, cxobj *x);
cxobj *xml_child_index_each(cxobj *xparent, char *name, cxobj *xprev, enum cxobj_type type);
#endif

View file

@ -877,8 +877,8 @@ xml_child_order(cxobj *xp,
* ...
* }
* @endcode
* @note makes uses _x_vector_i:can be changed if list changed between calls
* @note Never manipulate the child-list during operation or using the
* @note uses _x_vector_i as a shared resource: you cannot mix loops over same parent
* Further, never manipulate the child-list during operation or using the
* same object recursively, the function uses an internal field to remember the
* index used. It works as long as the same object is not iterated concurrently.
* If you need to delete a node you can do somethjing like:
@ -894,6 +894,9 @@ xml_child_order(cxobj *xp,
* }
* }
* @endcode
#ifdef XML_EXPLICIT_INDEX
* @see xml_child_index_each
#endif XML_EXPLICIT_INDEX
*/
cxobj *
xml_child_each(cxobj *xparent,
@ -922,6 +925,7 @@ xml_child_each(cxobj *xparent,
return xn;
}
/*! Extend child vector with one and insert xml node there
* @note does not do anything with child, you may need to set its parent, etc
* @see xml_child_insert_pos
@ -2581,4 +2585,55 @@ xml_search_child_rm(cxobj *xp,
return retval;
}
/*! Iterator over xml children objects using (explicit) index variable
*
* @param[in] xparent xml tree node whose children should be iterated
* @param[in] name Name of index variable
* @param[in] xprev previous child, or NULL on init
* @param[in] type matching type or -1 for any
* @code
* cxobj *x = NULL;
* while ((x = xml_child_index_each(x_top, "i", x, -1)) != NULL) {
* ...
* }
* @endcode
* @see xml_child_each for looping over structural children.
* @note uses _x_vector_i as a shared resource: you cannot mix loops over same parent
* Further, never manipulate the child-list during operation or using the
* same object recursively, the function uses an internal field to remember the
* index used. It works as long as the same object is not iterated concurrently.
* If you need to delete a node you can do somethjing like:
*/
cxobj *
xml_child_index_each(cxobj *xparent,
char *name,
cxobj *xprev,
enum cxobj_type type)
{
cxobj *xn = NULL;
clixon_xvec *xv = NULL;
int i;
if (xparent == NULL)
return NULL;
if (!is_element(xparent))
return NULL;
if (xml_search_vector_get(xparent, name, &xv) < 0)
return NULL;
if (xv == NULL)
return NULL;
for (i=xprev?xprev->_x_vector_i+1:0; i<clixon_xvec_len(xv); i++){
if ((xn = clixon_xvec_i(xv, i)) == NULL)
continue;
if (type != CX_ERROR && xml_type(xn) != type)
continue;
break; /* this is next object after previous */
}
if (i < clixon_xvec_len(xv)) /* found */
xn->_x_vector_i = i;
else
xn = NULL;
return xn;
}
#endif /* XML_EXPLICIT_INDEX */