diff --git a/example.c b/example.c index 0934321..9519529 100644 --- a/example.c +++ b/example.c @@ -57,12 +57,17 @@ int main(int argc, char** argv) { n = h->pre; if(n != NULL) { while(n != NULL) { - recursive(h, n, INDENT); +// recursive(h, n, INDENT); n = n->next; } } - if(h->root != NULL) recursive(h, h->root, INDENT); +// if(h->root != NULL) recursive(h, h->root, INDENT); + + xl_node_t** r = xl_get_path(h->root, "book.title"); + int j; + for(j = 0; r[j] != NULL; j++) recursive(h, r[j], INDENT); + free(r); } else { int j; for(j = 0; j < INDENT; j++) printf(" "); diff --git a/include/xemil.h b/include/xemil.h index 1d5359a..0928d4a 100644 --- a/include/xemil.h +++ b/include/xemil.h @@ -71,6 +71,9 @@ XLDECL int xl_parse(xemil_t* handle); XLDECL void xl_close(xemil_t* handle); XLDECL char* xl_get_attribute(xl_node_t* node, const char* key); +XLDECL xl_node_t** xl_get_nodes(xl_node_t* node, const char* name); /* NULL-terminated */ +XLDECL xl_node_t** xl_get_path(xl_node_t* node, const char* path); /* NULL-terminated */ + /* file.c */ XLDECL xl_driver_t* xl_driver_file; diff --git a/src/core.c b/src/core.c index b5c246d..3be6270 100644 --- a/src/core.c +++ b/src/core.c @@ -600,3 +600,86 @@ char* xl_get_attribute(xl_node_t* node, const char* key) { return NULL; } + +xl_node_t** xl_get_nodes(xl_node_t* node, const char* name){ + xl_node_t* child; + int i, len = 0; + xl_node_t** matches; + + child = node->first_child; + while(child != NULL){ + if(child->type == XL_NODE_NODE && child->name != NULL && strcmp(child->name, name) == 0){ + len++; + } + + child = child->next; + } + + if(len == 0) return NULL; + + matches = malloc(sizeof(*matches) * (len + 1)); + matches[len] = NULL; + + child = node->first_child; + while(child != NULL){ + if(child->type == XL_NODE_NODE && child->name != NULL && strcmp(child->name, name) == 0){ + matches[i++] = child; + } + + child = child->next; + } + + return matches; +} + +xl_node_t** xl_get_path(xl_node_t* node, const char* path){ + xl_node_t** r = malloc(sizeof(*r) * 2); + char* p = xl_util_strdup(path); + int i; + int s = 0; + + r[0] = node; + r[1] = NULL; + + for(i = 0;; i++){ + if(p[i] == '.' || p[i] == 0){ + char old = p[i]; + int j; + xl_node_t** new = malloc(sizeof(*new)); + + new[0] = NULL; + + p[i] = 0; + + for(j = 0; r[j] != NULL; j++){ + xl_node_t** nodes = xl_get_nodes(r[j], p + s); + if(nodes != NULL){ + xl_node_t** old = new; + int k, l; + int len = 0; + + for(k = 0; old[k] != NULL; k++) len++; + for(k = 0; nodes[k] != NULL; k++) len++; + + new = malloc(sizeof(*new) * (len + 1)); + new[len] = NULL; + + for(k = 0; old[k] != NULL; k++) new[k] = old[k]; + for(l = 0; nodes[l] != NULL; l++) new[k + l] = nodes[l]; + + free(old); + + free(nodes); + } + } + free(r); + r = new; + + s = i + 1; + + if(old == 0) break; + } + } + + return r; +}