struct node { enum { document_node, element_node, text_node } nodetype; struct nodedata *data; int n_children; struct node *child[0]; }; typedef int bool; struct visitor { void *visitor_data; bool (*document_callback)(struct visitor *self, struct nodedata*); void (*document_end_callback)(struct visitor *self, struct nodedata*); bool (*element_callback)(struct visitor *self, struct nodedata*); void (*element_end_callback)(struct visitor *self, struct nodedata*); void (*text_callback)(struct visitor *self, struct nodedata*); }; void visit_node(struct node *n, struct visitor *v); static inline void visit_children(struct node *n, struct visitor *v) { int ii; for (ii = 0; ii < n->n_children; ii++) { _visit_node(n->child[ii], v); } } static void _visit_node(struct node *n, struct visitor *v) { switch (n->nodetype) { case element_node: if (v->element_callback(v, n->data)) visit_children(n, v); v->element_end_callback(v, n->data); break; case document_node: if (v->document_callback(v, n->data)) visit_children(n, v); v->document_end_callback(v, n->data); break; case text_node: v->text_callback(v, n->data); break; } } void visit_node(struct node *n, struct visitor *v) { _visit_node(n, v); }