diff --git a/ChangeLog b/ChangeLog index 5760dced..59735384 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +Sun Oct 22 13:59:50 CEST 2000 Daniel Veillard + + * tree.c: coalesce adjacent text nodes + * valid.c: handling of blank nodes in DTd validation (raised + by problems with a posteriori validation). + * nanohttp.c: changing behaviour on HTTP write stuff. + * HTMLtree.c: forced body and html to be explicitely closed. + * xpath.h: exported more XPath functions. + Sun Oct 15 22:28:32 CEST 2000 Daniel Veillard * Release of 2.2.5 diff --git a/HTMLtree.c b/HTMLtree.c index c8e8a646..5465357d 100644 --- a/HTMLtree.c +++ b/HTMLtree.c @@ -849,9 +849,10 @@ htmlNodeDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur, const return; } if ((cur->content == NULL) && (cur->children == NULL)) { - if ((info != NULL) && (info->endTag != 0)) + if ((info != NULL) && (info->endTag != 0) && + (strcmp(info->name, "html")) && (strcmp(info->name, "body"))) { xmlOutputBufferWriteString(buf, ">"); - else { + } else { xmlOutputBufferWriteString(buf, ">name); xmlOutputBufferWriteString(buf, ">"); diff --git a/include/libxml/xpath.h b/include/libxml/xpath.h index 81a11f62..a0a55785 100644 --- a/include/libxml/xpath.h +++ b/include/libxml/xpath.h @@ -283,6 +283,9 @@ int valuePush (xmlXPathParserContextPtr ctxt, xmlXPathObjectPtr value); xmlXPathObjectPtr xmlXPathNewString (const xmlChar *val); +xmlXPathObjectPtr xmlXPathNewCString (const char *val); +xmlXPathObjectPtr xmlXPathNewFloat (double val); +xmlXPathObjectPtr xmlXPathNewBoolean (int val); xmlXPathObjectPtr xmlXPathNewNodeSet (xmlNodePtr val); void xmlXPathNodeSetAdd (xmlNodeSetPtr cur, xmlNodePtr val); diff --git a/nanohttp.c b/nanohttp.c index cb0468aa..a1cadd61 100644 --- a/nanohttp.c +++ b/nanohttp.c @@ -403,8 +403,17 @@ xmlNanoHTTPFreeCtxt(xmlNanoHTTPCtxtPtr ctxt) { static void xmlNanoHTTPSend(xmlNanoHTTPCtxtPtr ctxt) { - if (ctxt->state & XML_NANO_HTTP_WRITE) - ctxt->last = send(ctxt->fd, ctxt->outptr, strlen(ctxt->outptr), 0); + if (ctxt->state & XML_NANO_HTTP_WRITE) { + int total_sent = 0; + while (total_sent outptr)) { + int nsent = send(ctxt->fd, ctxt->outptr+total_sent, + strlen(ctxt->outptr)-total_sent, 0); + if (nsent>0) + total_sent += nsent; +} + + ctxt->last = total_sent; + } } /** diff --git a/tree.c b/tree.c index ae841c8c..497de9dc 100644 --- a/tree.c +++ b/tree.c @@ -1779,6 +1779,7 @@ xmlNewChild(xmlNodePtr parent, xmlNsPtr ns, * Add a new element @elem as the next siblings of @cur * If the new element was already inserted in a document it is * first unlinked from its existing context. + * As a result of text merging @elem may be freed. * * Returns the new element or NULL in case of error. */ @@ -1798,6 +1799,34 @@ xmlAddNextSibling(xmlNodePtr cur, xmlNodePtr elem) { } xmlUnlinkNode(elem); + + if (elem->type == XML_TEXT_NODE) { + if (cur->type == XML_TEXT_NODE) { +#ifndef XML_USE_BUFFER_CONTENT + xmlNodeAddContent(cur, elem->content); +#else + xmlNodeAddContent(cur, xmlBufferContent(elem->content)); +#endif + xmlFreeNode(elem); + return(cur); + } + if ((cur->next != NULL) && (cur->type == XML_TEXT_NODE)) { +#ifndef XML_USE_BUFFER_CONTENT + xmlChar *tmp; + + tmp = xmlStrdup(elem->content); + tmp = xmlStrcat(tmp, cur->next->content); + xmlNodeSetContent(cur->next, tmp); + xmlFree(tmp); +#else + xmlBufferAddHead(cur->next, xmlBufferContent(elem->content), + xmlBufferLength(elem->content)); +#endif + xmlFreeNode(elem); + return(cur->next); + } + } + elem->doc = cur->doc; elem->parent = cur->parent; elem->prev = cur; @@ -1816,6 +1845,7 @@ xmlAddNextSibling(xmlNodePtr cur, xmlNodePtr elem) { * @elem: the new node * * Add a new element @elem as the previous siblings of @cur + * merging adjacent TEXT nodes (@elem may be freed) * If the new element was already inserted in a document it is * first unlinked from its existing context. * @@ -1837,6 +1867,34 @@ xmlAddPrevSibling(xmlNodePtr cur, xmlNodePtr elem) { } xmlUnlinkNode(elem); + + if (elem->type == XML_TEXT_NODE) { + if (cur->type == XML_TEXT_NODE) { +#ifndef XML_USE_BUFFER_CONTENT + xmlChar *tmp; + + tmp = xmlStrdup(elem->content); + tmp = xmlStrcat(tmp, cur->content); + xmlNodeSetContent(cur, tmp); + xmlFree(tmp); +#else + xmlBufferAddHead(cur->content, xmlBufferContent(elem->content), + xmlBufferLength(elem->content)); +#endif + xmlFreeNode(elem); + return(cur); + } + if ((cur->prev != NULL) && (cur->prev->type == XML_TEXT_NODE)) { +#ifndef XML_USE_BUFFER_CONTENT + xmlNodeAddContent(cur->prev, elem->content); +#else + xmlNodeAddContent(cur->prev, xmlBufferContent(elem->content)); +#endif + xmlFreeNode(elem); + return(cur->prev); + } + } + elem->doc = cur->doc; elem->parent = cur->parent; elem->next = cur; @@ -1855,6 +1913,7 @@ xmlAddPrevSibling(xmlNodePtr cur, xmlNodePtr elem) { * @elem: the new node * * Add a new element @elem to the list of siblings of @cur + * merging adjacent TEXT nodes (@elem may be freed) * If the new element was already inserted in a document it is * first unlinked from its existing context. * @@ -1892,6 +1951,17 @@ xmlAddSibling(xmlNodePtr cur, xmlNodePtr elem) { } xmlUnlinkNode(elem); + + if ((cur->type == XML_TEXT_NODE) && (elem->type == XML_TEXT_NODE)) { +#ifndef XML_USE_BUFFER_CONTENT + xmlNodeAddContent(cur, elem->content); +#else + xmlNodeAddContent(cur, xmlBufferContent(elem->content)); +#endif + xmlFreeNode(elem); + return(cur); + } + if (elem->doc == NULL) elem->doc = cur->doc; /* the parent may not be linked to a doc ! */ @@ -1912,6 +1982,7 @@ xmlAddSibling(xmlNodePtr cur, xmlNodePtr elem) { * @cur: the first node in the list * * Add a list of node at the end of the child list of the parent + * merging adjacent TEXT nodes (@cur may be freed) * * Returns the last child or NULL in case of error. */ @@ -1946,6 +2017,27 @@ xmlAddChildList(xmlNodePtr parent, xmlNodePtr cur) { if (parent->children == NULL) { parent->children = cur; } else { + /* + * If cur and parent->last both are TEXT nodes, then merge them. + */ + if ((cur->type == XML_TEXT_NODE) && + (parent->last->type == XML_TEXT_NODE)) { +#ifndef XML_USE_BUFFER_CONTENT + xmlNodeAddContent(parent->last, cur->content); +#else + xmlNodeAddContent(parent->last, xmlBufferContent(cur->content)); +#endif + /* + * if it's the only child, nothing more to be done. + */ + if (cur->next == NULL) { + xmlFreeNode(cur); + return(parent->last); + } + prev = cur; + cur = cur->next; + xmlFreeNode(prev); + } prev = parent->last; prev->next = cur; cur->prev = prev; @@ -1967,7 +2059,8 @@ xmlAddChildList(xmlNodePtr parent, xmlNodePtr cur) { * @parent: the parent node * @cur: the child node * - * Add a new child element, to @parent, at the end of the child list. + * Add a new child element, to @parent, at the end of the child list + * merging adjacent TEXT nodes (in which case @cur is freed) * Returns the child or NULL in case of error. */ xmlNodePtr @@ -1995,6 +2088,34 @@ xmlAddChild(xmlNodePtr parent, xmlNodePtr cur) { #endif } + /* + * If cur is a TEXT node, merge its content with adjacent TEXT nodes + * or with parent->content if parent->content != NULL. + * cur is then freed. + */ + if (cur->type == XML_TEXT_NODE) { + if (((parent->type == XML_ELEMENT_NODE) || + (parent->type == XML_TEXT_NODE)) && + (parent->content != NULL)) { +#ifndef XML_USE_BUFFER_CONTENT + xmlNodeAddContent(parent, cur->content); +#else + xmlNodeAddContent(parent, xmlBufferContent(cur->content)); +#endif + xmlFreeNode(cur); + return(parent); + } + if ((parent->last != NULL) && (parent->last->type == XML_TEXT_NODE)) { +#ifndef XML_USE_BUFFER_CONTENT + xmlNodeAddContent(parent->last, cur->content); +#else + xmlNodeAddContent(parent->last, xmlBufferContent(cur->content)); +#endif + xmlFreeNode(cur); + return(parent->last); + } + } + /* * add the new element at the end of the children list. */ diff --git a/valid.c b/valid.c index 28d6c9d9..2e4240a0 100644 --- a/valid.c +++ b/valid.c @@ -3505,9 +3505,19 @@ xmlValidateElementTypeElement(xmlValidCtxtPtr ctxt, xmlNodePtr *child, *child = cur; return(0); } + if (ret == -1) return(-1); + cur = *child; do { - cur = *child; + if (*child == NULL) + break; /* while */ + if (((*child)->type == XML_TEXT_NODE) && + (xmlIsBlankNode(*child))) { + *child = (*child)->next; + continue; + } ret = xmlValidateElementTypeExpr(ctxt, child, cont); + if (ret == 1) + cur = *child; } while (ret == 1); if (ret == -1) return(-1); *child = cur; @@ -3812,6 +3822,11 @@ child_ok: child = elem->children; cont = elemDecl->content; ret = xmlValidateElementTypeElement(ctxt, &child, cont); + while ((child != NULL) && (child->type == XML_TEXT_NODE) && + (xmlIsBlankNode(child))) { + child = child->next; + continue; + } if ((ret == 0) || (child != NULL)) { char expr[1000]; char list[2000]; diff --git a/xpath.h b/xpath.h index 81a11f62..a0a55785 100644 --- a/xpath.h +++ b/xpath.h @@ -283,6 +283,9 @@ int valuePush (xmlXPathParserContextPtr ctxt, xmlXPathObjectPtr value); xmlXPathObjectPtr xmlXPathNewString (const xmlChar *val); +xmlXPathObjectPtr xmlXPathNewCString (const char *val); +xmlXPathObjectPtr xmlXPathNewFloat (double val); +xmlXPathObjectPtr xmlXPathNewBoolean (int val); xmlXPathObjectPtr xmlXPathNewNodeSet (xmlNodePtr val); void xmlXPathNodeSetAdd (xmlNodeSetPtr cur, xmlNodePtr val);