add xl_get_nodes and xl_get_path

This commit is contained in:
Nishi 2026-03-02 07:14:13 +09:00
commit e8f00f4111
Signed by: nishi
GPG key ID: 27EF69B208EB9343
3 changed files with 93 additions and 2 deletions

View file

@ -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(" ");

View file

@ -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;

View file

@ -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;
}