common/xml: let LAB_XML_FOR_EACH() skip first child text nodes

Before this patch, first text nodes like the spaces between <a> and <b>
below were also travered by LAB_XML_FOR_EACH():

  <a>  <b>foo</b></a>
This commit is contained in:
tokyo4j 2025-08-03 00:02:02 +09:00 committed by Johan Malm
parent b9c84f9c38
commit 5a50d87ee2

View file

@ -35,16 +35,13 @@ bool lab_xml_get_string(xmlNode *node, const char *key, char *s, size_t len);
bool lab_xml_get_int(xmlNode *node, const char *key, int *i);
bool lab_xml_get_bool(xmlNode *node, const char *key, bool *b);
/* also skips other unusual nodes like comments */
static inline xmlNode *
lab_xml_get_next_child(xmlNode *child)
lab_xml_skip_text(xmlNode *child)
{
if (!child) {
return NULL;
}
do {
while (child && child->type != XML_ELEMENT_NODE) {
child = child->next;
} while (child && child->type != XML_ELEMENT_NODE);
}
return child;
}
@ -58,11 +55,13 @@ lab_xml_get_key_and_content(xmlNode *node, char **name, char **content)
}
#define LAB_XML_FOR_EACH(parent, child, key, content) \
for ((child) = (parent)->children, \
for ((child) = lab_xml_skip_text((parent)->children), \
lab_xml_get_key_and_content((child), &(key), &(content)); \
\
(child); \
\
xmlFree((xmlChar *)(content)), \
(child) = lab_xml_get_next_child(child), \
(child) = lab_xml_skip_text((child)->next), \
lab_xml_get_key_and_content((child), &(key), &(content)))
#endif /* LABWC_XML_H */