diff options
author | Wilmer van der Gaast <wilmer@gaast.net> | 2010-08-15 00:00:53 +0100 |
---|---|---|
committer | Wilmer van der Gaast <wilmer@gaast.net> | 2010-08-15 00:00:53 +0100 |
commit | d912fe4783cc9f5c2e7204f810df420359d5bee8 (patch) | |
tree | 4ce2a497d76a44c47b6dcece559750067af7758e /lib/xmltree.c | |
parent | 4fc95c57361193c5338d9916fd37cc8a939067cd (diff) |
Add xt_find_path() to simplify digging through multi-level XML trees.
Diffstat (limited to 'lib/xmltree.c')
-rw-r--r-- | lib/xmltree.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/lib/xmltree.c b/lib/xmltree.c index 5fd43014..20d69455 100644 --- a/lib/xmltree.c +++ b/lib/xmltree.c @@ -478,6 +478,46 @@ struct xt_node *xt_find_node( struct xt_node *node, const char *name ) return node; } +/* More advanced than the one above, understands something like + ../foo/bar to find a subnode bar of a node foo which is a child + of node's parent. Pass the node directly, not its list of children. */ +struct xt_node *xt_find_path( struct xt_node *node, const char *name ) +{ + while( name && *name && node ) + { + char *colon, *slash; + int n; + + if( ( slash = strchr( name, '/' ) ) ) + n = slash - name; + else + n = strlen( name ); + + if( strncmp( name, "..", n ) == 0 ) + { + node = node->parent; + } + else + { + node = node->children; + + while( node ) + { + if( g_strncasecmp( node->name, name, n ) == 0 || + ( ( colon = strchr( node->name, ':' ) ) && + g_strncasecmp( colon + 1, name, n ) == 0 ) ) + break; + + node = node->next; + } + } + + name = slash ? slash + 1 : NULL; + } + + return node; +} + char *xt_find_attr( struct xt_node *node, const char *key ) { int i; |