From: Martin Mares Date: Thu, 12 Feb 2015 19:04:55 +0000 (+0100) Subject: More clean OSM XML parsing X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=33ef89b1a058aef1e47cdf5a2cd2ed3249dae9cb;hp=9e0796f5be17bd5e65c31865cac25d38c8b2a0fb;p=leo.git More clean OSM XML parsing --- diff --git a/xml.c b/xml.c index 6ba9427..69e739d 100644 --- a/xml.c +++ b/xml.c @@ -1,9 +1,11 @@ /* * Hic Est Leo -- OSM XML Parser * - * (c) 2014 Martin Mares + * (c) 2014--2015 Martin Mares */ +#undef LOCAL_DEBUG + #include #include #include @@ -159,30 +161,36 @@ static void parse_element(struct xml_context *ctx, struct xml_node *e) void osm_xml_parse(const char *name) { - struct xml_context ctx; - xml_init(&ctx); - ctx.h_warn = ctx.h_error = ctx.h_fatal = h_error; - xml_push_fastbuf(&ctx, bopen_file(name, O_RDONLY, NULL)); + struct xml_context xml_ctx, *ctx = &xml_ctx; + xml_init(ctx); + ctx->h_warn = ctx->h_error = ctx->h_fatal = h_error; + xml_push_fastbuf(ctx, bopen_file(name, O_RDONLY, NULL)); uint state; - while (state = xml_next_state(&ctx, XML_PULL_STAG)) - switch (state) + while (state = xml_next_state(ctx, XML_PULL_STAG)) + if (state == XML_STATE_STAG) { - case XML_STATE_STAG: - // printf("STAG %s\n", ctx.node->name); - if (strcmp(ctx.node->name, "osm")) + DBG("Level 1 tag <%s>", ctx->node->name); + if (!strcmp(ctx->node->name, "osm")) { - ctx.flags |= XML_ALLOC_CHARS | XML_ALLOC_TAGS; - if (xml_skip_element(&ctx) == XML_STATE_ETAG) + DBG("Switched to level 2"); + while ((state = xml_next_state(ctx, XML_PULL_STAG | XML_PULL_ETAG)) == XML_STATE_STAG) { - // printf("ETAG %s\n", ctx.node->name); - parse_element(&ctx, ctx.node); + ctx->flags |= XML_ALLOC_CHARS | XML_ALLOC_TAGS; + if (xml_skip_element(ctx) == XML_STATE_ETAG) + { + DBG("Level 2 tag <%s>", ctx->node->name); + parse_element(ctx, ctx->node); + } } + DBG("Exited level 2 in state %u", state); } + else + xml_skip_element(ctx); } - if (ctx.err_code) + if (ctx->err_code) die("Fatal error in XML parser"); - xml_cleanup(&ctx); + xml_cleanup(ctx); }