aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilmer van der Gaast <wilmer@gaast.net>2010-08-15 00:00:53 +0100
committerWilmer van der Gaast <wilmer@gaast.net>2010-08-15 00:00:53 +0100
commitd912fe4783cc9f5c2e7204f810df420359d5bee8 (patch)
tree4ce2a497d76a44c47b6dcece559750067af7758e
parent4fc95c57361193c5338d9916fd37cc8a939067cd (diff)
Add xt_find_path() to simplify digging through multi-level XML trees.
-rw-r--r--lib/xmltree.c40
-rw-r--r--lib/xmltree.h1
2 files changed, 41 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;
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 );