* 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:
parent
1a1aa58249
commit
6629f3d780
3 changed files with 63 additions and 2 deletions
|
|
@ -25,6 +25,10 @@
|
||||||
## 4.6.0
|
## 4.6.0
|
||||||
Expected: July 2020
|
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
|
## 4.5.0
|
||||||
12 May 2020
|
12 May 2020
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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_vector_get(cxobj *x, char *name, clixon_xvec **xvec);
|
||||||
int xml_search_child_insert(cxobj *xp, cxobj *x);
|
int xml_search_child_insert(cxobj *xp, cxobj *x);
|
||||||
int xml_search_child_rm(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
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -877,8 +877,8 @@ xml_child_order(cxobj *xp,
|
||||||
* ...
|
* ...
|
||||||
* }
|
* }
|
||||||
* @endcode
|
* @endcode
|
||||||
* @note makes uses _x_vector_i:can be changed if list changed between calls
|
* @note uses _x_vector_i as a shared resource: you cannot mix loops over same parent
|
||||||
* @note Never manipulate the child-list during operation or using the
|
* Further, never manipulate the child-list during operation or using the
|
||||||
* same object recursively, the function uses an internal field to remember 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.
|
* 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:
|
* If you need to delete a node you can do somethjing like:
|
||||||
|
|
@ -894,6 +894,9 @@ xml_child_order(cxobj *xp,
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
* @endcode
|
* @endcode
|
||||||
|
#ifdef XML_EXPLICIT_INDEX
|
||||||
|
* @see xml_child_index_each
|
||||||
|
#endif XML_EXPLICIT_INDEX
|
||||||
*/
|
*/
|
||||||
cxobj *
|
cxobj *
|
||||||
xml_child_each(cxobj *xparent,
|
xml_child_each(cxobj *xparent,
|
||||||
|
|
@ -922,6 +925,7 @@ xml_child_each(cxobj *xparent,
|
||||||
return xn;
|
return xn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! Extend child vector with one and insert xml node there
|
/*! 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
|
* @note does not do anything with child, you may need to set its parent, etc
|
||||||
* @see xml_child_insert_pos
|
* @see xml_child_insert_pos
|
||||||
|
|
@ -2581,4 +2585,55 @@ xml_search_child_rm(cxobj *xp,
|
||||||
return retval;
|
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 */
|
#endif /* XML_EXPLICIT_INDEX */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue