From d912fe4783cc9f5c2e7204f810df420359d5bee8 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 15 Aug 2010 00:00:53 +0100 Subject: Add xt_find_path() to simplify digging through multi-level XML trees. --- lib/xmltree.c | 40 ++++++++++++++++++++++++++++++++++++++++ lib/xmltree.h | 1 + 2 files changed, 41 insertions(+) (limited to 'lib') 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; diff --git a/lib/xmltree.h b/lib/xmltree.h index c1697ff5..5a0dbc8e 100644 --- a/lib/xmltree.h +++ b/lib/xmltree.h @@ -88,6 +88,7 @@ struct xt_node *xt_dup( struct xt_node *node ); void xt_free_node( struct xt_node *node ); void xt_free( struct xt_parser *xt ); struct xt_node *xt_find_node( struct xt_node *node, const char *name ); +struct xt_node *xt_find_path( struct xt_node *node, const char *name ); char *xt_find_attr( struct xt_node *node, const char *key ); struct xt_node *xt_new_node( char *name, const char *text, struct xt_node *children ); -- cgit v1.2.3