diff --git a/valid.c b/valid.c index fca3cc06..eaccb11e 100644 --- a/valid.c +++ b/valid.c @@ -1147,82 +1147,103 @@ xmlFreeElementContent(xmlElementContentPtr cur) { } #ifdef LIBXML_OUTPUT_ENABLED +/** + * xmlDumpElementOccur: + * @buf: An XML buffer + * @cur: An element table + * + * Dump the occurence operator of an element. + */ +static void +xmlDumpElementOccur(xmlBufferPtr buf, xmlElementContentPtr cur) { + switch (cur->ocur) { + case XML_ELEMENT_CONTENT_ONCE: + break; + case XML_ELEMENT_CONTENT_OPT: + xmlBufferWriteChar(buf, "?"); + break; + case XML_ELEMENT_CONTENT_MULT: + xmlBufferWriteChar(buf, "*"); + break; + case XML_ELEMENT_CONTENT_PLUS: + xmlBufferWriteChar(buf, "+"); + break; + } +} + /** * xmlDumpElementContent: * @buf: An XML buffer * @content: An element table - * @glob: 1 if one must print the englobing parenthesis, 0 otherwise * * This will dump the content of the element table as an XML DTD definition */ static void -xmlDumpElementContent(xmlBufferPtr buf, xmlElementContentPtr content, int glob) { +xmlDumpElementContent(xmlBufferPtr buf, xmlElementContentPtr content) { + xmlElementContentPtr cur; + if (content == NULL) return; - if (glob) xmlBufferWriteChar(buf, "("); - switch (content->type) { - case XML_ELEMENT_CONTENT_PCDATA: - xmlBufferWriteChar(buf, "#PCDATA"); - break; - case XML_ELEMENT_CONTENT_ELEMENT: - if (content->prefix != NULL) { - xmlBufferWriteCHAR(buf, content->prefix); - xmlBufferWriteChar(buf, ":"); - } - xmlBufferWriteCHAR(buf, content->name); - break; - case XML_ELEMENT_CONTENT_SEQ: - if ((content->c1 != NULL) && - ((content->c1->type == XML_ELEMENT_CONTENT_OR) || - (content->c1->type == XML_ELEMENT_CONTENT_SEQ))) - xmlDumpElementContent(buf, content->c1, 1); - else - xmlDumpElementContent(buf, content->c1, 0); - xmlBufferWriteChar(buf, " , "); - if ((content->c2 != NULL) && - ((content->c2->type == XML_ELEMENT_CONTENT_OR) || - ((content->c2->type == XML_ELEMENT_CONTENT_SEQ) && - (content->c2->ocur != XML_ELEMENT_CONTENT_ONCE)))) - xmlDumpElementContent(buf, content->c2, 1); - else - xmlDumpElementContent(buf, content->c2, 0); - break; - case XML_ELEMENT_CONTENT_OR: - if ((content->c1 != NULL) && - ((content->c1->type == XML_ELEMENT_CONTENT_OR) || - (content->c1->type == XML_ELEMENT_CONTENT_SEQ))) - xmlDumpElementContent(buf, content->c1, 1); - else - xmlDumpElementContent(buf, content->c1, 0); - xmlBufferWriteChar(buf, " | "); - if ((content->c2 != NULL) && - ((content->c2->type == XML_ELEMENT_CONTENT_SEQ) || - ((content->c2->type == XML_ELEMENT_CONTENT_OR) && - (content->c2->ocur != XML_ELEMENT_CONTENT_ONCE)))) - xmlDumpElementContent(buf, content->c2, 1); - else - xmlDumpElementContent(buf, content->c2, 0); - break; - default: - xmlErrValid(NULL, XML_ERR_INTERNAL_ERROR, - "Internal: ELEMENT content corrupted invalid type\n", - NULL); - } - if (glob) - xmlBufferWriteChar(buf, ")"); - switch (content->ocur) { - case XML_ELEMENT_CONTENT_ONCE: - break; - case XML_ELEMENT_CONTENT_OPT: - xmlBufferWriteChar(buf, "?"); - break; - case XML_ELEMENT_CONTENT_MULT: - xmlBufferWriteChar(buf, "*"); - break; - case XML_ELEMENT_CONTENT_PLUS: - xmlBufferWriteChar(buf, "+"); - break; - } + xmlBufferWriteChar(buf, "("); + cur = content; + + do { + if (cur == NULL) return; + + switch (cur->type) { + case XML_ELEMENT_CONTENT_PCDATA: + xmlBufferWriteChar(buf, "#PCDATA"); + break; + case XML_ELEMENT_CONTENT_ELEMENT: + if (cur->prefix != NULL) { + xmlBufferWriteCHAR(buf, cur->prefix); + xmlBufferWriteChar(buf, ":"); + } + xmlBufferWriteCHAR(buf, cur->name); + break; + case XML_ELEMENT_CONTENT_SEQ: + case XML_ELEMENT_CONTENT_OR: + if ((cur != content) && + (cur->parent != NULL) && + ((cur->type != cur->parent->type) || + (cur->ocur != XML_ELEMENT_CONTENT_ONCE))) + xmlBufferWriteChar(buf, "("); + cur = cur->c1; + continue; + default: + xmlErrValid(NULL, XML_ERR_INTERNAL_ERROR, + "Internal: ELEMENT cur corrupted invalid type\n", + NULL); + } + + while (cur != content) { + xmlElementContentPtr parent = cur->parent; + + if (parent == NULL) return; + + if (((cur->type == XML_ELEMENT_CONTENT_OR) || + (cur->type == XML_ELEMENT_CONTENT_SEQ)) && + ((cur->type != parent->type) || + (cur->ocur != XML_ELEMENT_CONTENT_ONCE))) + xmlBufferWriteChar(buf, ")"); + xmlDumpElementOccur(buf, cur); + + if (cur == parent->c1) { + if (parent->type == XML_ELEMENT_CONTENT_SEQ) + xmlBufferWriteChar(buf, " , "); + else if (parent->type == XML_ELEMENT_CONTENT_OR) + xmlBufferWriteChar(buf, " | "); + + cur = parent->c2; + break; + } + + cur = parent; + } + } while (cur != content); + + xmlBufferWriteChar(buf, ")"); + xmlDumpElementOccur(buf, content); } /** @@ -1703,7 +1724,7 @@ xmlDumpElementDecl(xmlBufferPtr buf, xmlElementPtr elem) { } xmlBufferWriteCHAR(buf, elem->name); xmlBufferWriteChar(buf, " "); - xmlDumpElementContent(buf, elem->content, 1); + xmlDumpElementContent(buf, elem->content); xmlBufferWriteChar(buf, ">\n"); break; case XML_ELEMENT_TYPE_ELEMENT: @@ -1714,7 +1735,7 @@ xmlDumpElementDecl(xmlBufferPtr buf, xmlElementPtr elem) { } xmlBufferWriteCHAR(buf, elem->name); xmlBufferWriteChar(buf, " "); - xmlDumpElementContent(buf, elem->content, 1); + xmlDumpElementContent(buf, elem->content); xmlBufferWriteChar(buf, ">\n"); break; default: