Gee.ArrayQueue<string> stack;
bool assigned = false;

void on_start (MarkupParseContext ctx,
               string name,
               string[] attribute_names,
               string[] attribute_values) throws MarkupError {
    if (name == "Categories") {
        return;
    }

    if (name != "Category") {
        return;
    }

    Workaround.markup_collect_attributes (name, attribute_names, attribute_values,
                               Markup.CollectType.BOOLEAN,
                                    "Assigned", out assigned,
                                    null);
}

void on_end (MarkupParseContext ctx, string name) throws MarkupError {
    if (name == "Category") {
        stack.poll_tail ();
    }

    if (name == "Categories") {
        assert (stack.is_empty);
    }
}

void on_text (MarkupParseContext ctx, string text) throws MarkupError {
    if (text == "")
        return;

    stack.offer_tail (text);
    if (assigned) {
        print ("\n");
        foreach (var f in stack) {
            print("%s|", f);
        }
    }
    assigned = false;
}

void on_error (MarkupParseContext ctx, Error error) {
}

int main(string[] args) {
    stack = new Gee.ArrayQueue<string>();
    string markup = "<Categories><Category Assigned=\"0\">6 Level<Category Assigned=\"1\">6.2 Level<Category Assigned=\"0\">6.3 Level<Category Assigned=\"0\">6.4 Level<Category Assigned=\"1\">6.5 Level</Category></Category></Category></Category></Category></Categories>";
    var parser = MarkupParser ();
    parser.start_element = on_start;
    parser.end_element = on_end;
    parser.text = on_text;
    parser.error = on_error;

    var ctx = new MarkupParseContext (parser, 0, null, null);
    try {
        ctx.parse (markup, markup.length);
    } catch (Error error) {
        warning ("Error parsing tags: %s", error.message);
    }

    return 0;
}
