xmlRelaxNGDumpDefine(FILE * output, xmlRelaxNGDefinePtr define)
{
    if (define == NULL)
        return;
    switch (define->type) {
        case XML_RELAXNG_EMPTY:
            fprintf(output, "<empty/>\n");
            break;
        case XML_RELAXNG_NOT_ALLOWED:
            fprintf(output, "<notAllowed/>\n");
            break;
        case XML_RELAXNG_TEXT:
            fprintf(output, "<text/>\n");
            break;
        case XML_RELAXNG_ELEMENT:
            fprintf(output, "<element>\n");
            if (define->name != NULL) {
                fprintf(output, "<name");
                if (define->ns != NULL)
                    fprintf(output, " ns=\"%s\"", define->ns);
                fprintf(output, ">%s</name>\n", define->name);
            }
            xmlRelaxNGDumpDefines(output, define->attrs);
            xmlRelaxNGDumpDefines(output, define->content);
            fprintf(output, "</element>\n");
            break;
        case XML_RELAXNG_LIST:
            fprintf(output, "<list>\n");
            xmlRelaxNGDumpDefines(output, define->content);
            fprintf(output, "</list>\n");
            break;
        case XML_RELAXNG_ONEORMORE:
            fprintf(output, "<oneOrMore>\n");
            xmlRelaxNGDumpDefines(output, define->content);
            fprintf(output, "</oneOrMore>\n");
            break;
        case XML_RELAXNG_ZEROORMORE:
            fprintf(output, "<zeroOrMore>\n");
            xmlRelaxNGDumpDefines(output, define->content);
            fprintf(output, "</zeroOrMore>\n");
            break;
        case XML_RELAXNG_CHOICE:
            fprintf(output, "<choice>\n");
            xmlRelaxNGDumpDefines(output, define->content);
            fprintf(output, "</choice>\n");
            break;
        case XML_RELAXNG_GROUP:
            fprintf(output, "<group>\n");
            xmlRelaxNGDumpDefines(output, define->content);
            fprintf(output, "</group>\n");
            break;
        case XML_RELAXNG_INTERLEAVE:
            fprintf(output, "<interleave>\n");
            xmlRelaxNGDumpDefines(output, define->content);
            fprintf(output, "</interleave>\n");
            break;
        case XML_RELAXNG_OPTIONAL:
            fprintf(output, "<optional>\n");
            xmlRelaxNGDumpDefines(output, define->content);
            fprintf(output, "</optional>\n");
            break;
        case XML_RELAXNG_ATTRIBUTE:
            fprintf(output, "<attribute>\n");
            xmlRelaxNGDumpDefines(output, define->content);
            fprintf(output, "</attribute>\n");
            break;
        case XML_RELAXNG_DEF:
            fprintf(output, "<define");
            if (define->name != NULL)
                fprintf(output, " name=\"%s\"", define->name);
            fprintf(output, ">\n");
            xmlRelaxNGDumpDefines(output, define->content);
            fprintf(output, "</define>\n");
            break;
        case XML_RELAXNG_REF:
            fprintf(output, "<ref");
            if (define->name != NULL)
                fprintf(output, " name=\"%s\"", define->name);
            fprintf(output, ">\n");
            xmlRelaxNGDumpDefines(output, define->content);
            fprintf(output, "</ref>\n");
            break;
        case XML_RELAXNG_PARENTREF:
            fprintf(output, "<parentRef");
            if (define->name != NULL)
                fprintf(output, " name=\"%s\"", define->name);
            fprintf(output, ">\n");
            xmlRelaxNGDumpDefines(output, define->content);
            fprintf(output, "</parentRef>\n");
            break;
        case XML_RELAXNG_EXTERNALREF:
            fprintf(output, "<externalRef>");
            xmlRelaxNGDumpDefines(output, define->content);
            fprintf(output, "</externalRef>\n");
            break;
        case XML_RELAXNG_DATATYPE:
        case XML_RELAXNG_VALUE:
            TODO break;
        case XML_RELAXNG_START:
        case XML_RELAXNG_EXCEPT:
        case XML_RELAXNG_PARAM:
            TODO break;
        case XML_RELAXNG_NOOP:
            xmlRelaxNGDumpDefines(output, define->content);
            break;
    }
}