xmlRelaxNGParseAttribute(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
{
    xmlRelaxNGDefinePtr ret, cur;
    xmlNodePtr child;
    int old_flags;

    ret = xmlRelaxNGNewDefine(ctxt, node);
    if (ret == NULL)
        return (NULL);
    ret->type = XML_RELAXNG_ATTRIBUTE;
    ret->parent = ctxt->def;
    child = node->children;
    if (child == NULL) {
        xmlRngPErr(ctxt, node, XML_RNGP_ATTRIBUTE_EMPTY,
                   "xmlRelaxNGParseattribute: attribute has no children\n",
                   NULL, NULL);
        return (ret);
    }
    old_flags = ctxt->flags;
    ctxt->flags |= XML_RELAXNG_IN_ATTRIBUTE;
    cur = xmlRelaxNGParseNameClass(ctxt, child, ret);
    if (cur != NULL)
        child = child->next;

    if (child != NULL) {
        cur = xmlRelaxNGParsePattern(ctxt, child);
        if (cur != NULL) {
            switch (cur->type) {
                case XML_RELAXNG_EMPTY:
                case XML_RELAXNG_NOT_ALLOWED:
                case XML_RELAXNG_TEXT:
                case XML_RELAXNG_ELEMENT:
                case XML_RELAXNG_DATATYPE:
                case XML_RELAXNG_VALUE:
                case XML_RELAXNG_LIST:
                case XML_RELAXNG_REF:
                case XML_RELAXNG_PARENTREF:
                case XML_RELAXNG_EXTERNALREF:
                case XML_RELAXNG_DEF:
                case XML_RELAXNG_ONEORMORE:
                case XML_RELAXNG_ZEROORMORE:
                case XML_RELAXNG_OPTIONAL:
                case XML_RELAXNG_CHOICE:
                case XML_RELAXNG_GROUP:
                case XML_RELAXNG_INTERLEAVE:
                case XML_RELAXNG_ATTRIBUTE:
                    ret->content = cur;
                    cur->parent = ret;
                    break;
                case XML_RELAXNG_START:
                case XML_RELAXNG_PARAM:
                case XML_RELAXNG_EXCEPT:
                    xmlRngPErr(ctxt, node, XML_RNGP_ATTRIBUTE_CONTENT,
                               "attribute has invalid content\n", NULL,
                               NULL);
                    break;
                case XML_RELAXNG_NOOP:
                    xmlRngPErr(ctxt, node, XML_RNGP_ATTRIBUTE_NOOP,
                               "RNG Internal error, noop found in attribute\n",
                               NULL, NULL);
                    break;
            }
        }
        child = child->next;
    }
    if (child != NULL) {
        xmlRngPErr(ctxt, node, XML_RNGP_ATTRIBUTE_CHILDREN,
                   "attribute has multiple children\n", NULL, NULL);
    }
    ctxt->flags = old_flags;
    return (ret);
}
xmlRelaxNGParseAttribute(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
{
    xmlRelaxNGDefinePtr ret, cur;
    xmlNodePtr child;
    int old_flags;

    ret = xmlRelaxNGNewDefine(ctxt, node);
    if (ret == NULL)
        return (NULL);
    ret->type = XML_RELAXNG_ATTRIBUTE;
    ret->parent = ctxt->def;
    child = node->children;
    if (child == NULL) {
        xmlRngPErr(ctxt, node, XML_RNGP_ATTRIBUTE_EMPTY,
                   "xmlRelaxNGParseattribute: attribute has no children\n",
                   NULL, NULL);
        return (ret);
    }
    old_flags = ctxt->flags;
    ctxt->flags |= XML_RELAXNG_IN_ATTRIBUTE;
    cur = xmlRelaxNGParseNameClass(ctxt, child, ret);
    if (cur != NULL)
        child = child->next;

    if (child != NULL) {
        cur = xmlRelaxNGParsePattern(ctxt, child);
        if (cur != NULL) {
            switch (cur->type) {
                case XML_RELAXNG_EMPTY:
                case XML_RELAXNG_NOT_ALLOWED:
                case XML_RELAXNG_TEXT:
                case XML_RELAXNG_ELEMENT:
                case XML_RELAXNG_DATATYPE:
                case XML_RELAXNG_VALUE:
                case XML_RELAXNG_LIST:
                case XML_RELAXNG_REF:
                case XML_RELAXNG_PARENTREF:
                case XML_RELAXNG_EXTERNALREF:
                case XML_RELAXNG_DEF:
                case XML_RELAXNG_ONEORMORE:
                case XML_RELAXNG_ZEROORMORE:
                case XML_RELAXNG_OPTIONAL:
                case XML_RELAXNG_CHOICE:
                case XML_RELAXNG_GROUP:
                case XML_RELAXNG_INTERLEAVE:
                case XML_RELAXNG_ATTRIBUTE:
                    ret->content = cur;
                    cur->parent = ret;
                    break;
                case XML_RELAXNG_START:
                case XML_RELAXNG_PARAM:
                case XML_RELAXNG_EXCEPT:
                    xmlRngPErr(ctxt, node, XML_RNGP_ATTRIBUTE_CONTENT,
                               "attribute has invalid content\n", NULL,
                               NULL);
                    break;
                case XML_RELAXNG_NOOP:
                    xmlRngPErr(ctxt, node, XML_RNGP_ATTRIBUTE_NOOP,
                               "RNG Internal error, noop found in attribute\n",
                               NULL, NULL);
                    break;
            }
        }
        child = child->next;
    }
    if (child != NULL) {
        xmlRngPErr(ctxt, node, XML_RNGP_ATTRIBUTE_CHILDREN,
                   "attribute has multiple children\n", NULL, NULL);
    }
    ctxt->flags = old_flags;
    return (ret);
}