--- php-4.1.1/ext/domxml/php_domxml.c.orig Tue Jan 29 14:33:48 2002 +++ php-4.1.1/ext/domxml/php_domxml.c Mon Feb 11 23:29:46 2002 @@ -151,6 +151,8 @@ PHP_FE(xmldocfile, NULL) PHP_FE(xmltree, NULL) PHP_FE(domxml_add_root, NULL) + PHP_FE(domxml_get_root, NULL) + PHP_FE(domxml_set_root, NULL) PHP_FE(domxml_dumpmem, NULL) PHP_FE(domxml_node_attributes, NULL) PHP_FE(domxml_elem_get_attribute, NULL) @@ -158,6 +160,7 @@ PHP_FE(domxml_node_children, NULL) PHP_FE(domxml_node_new_child, NULL) PHP_FE(domxml_node, NULL) + PHP_FE(domxml_text_node, NULL) PHP_FE(domxml_node_unlink_node, NULL) PHP_FE(domxml_node_set_content, NULL) PHP_FE(domxml_new_xmldoc, NULL) @@ -204,6 +207,8 @@ PHP_FALIAS(create_processing_instruction, domxml_doc_create_processing_instruction, NULL) PHP_FALIAS(children, domxml_node_children, NULL) PHP_FALIAS(add_root, domxml_add_root, NULL) + PHP_FALIAS(get_root, domxml_get_root, NULL) + PHP_FALIAS(set_root, domxml_set_root, NULL) PHP_FALIAS(imported_node, domxml_doc_imported_node, NULL) PHP_FALIAS(dtd, domxml_intdtd, NULL) PHP_FALIAS(dumpmem, domxml_dumpmem, NULL) @@ -240,6 +245,7 @@ PHP_FALIAS(child_nodes, domxml_node_children, NULL) PHP_FALIAS(previous_sibling, domxml_node_previous_sibling, NULL) PHP_FALIAS(next_sibling, domxml_node_next_sibling, NULL) + PHP_FALIAS(has_attributes, domxml_node_has_attributes, NULL) PHP_FALIAS(has_child_nodes, domxml_node_has_child_nodes, NULL) PHP_FALIAS(prefix, domxml_node_prefix, NULL) PHP_FALIAS(parent, domxml_node_parent, NULL) @@ -258,6 +264,7 @@ PHP_FALIAS(node_type, domxml_node_type, NULL) PHP_FALIAS(node_value, domxml_node_value, NULL) PHP_FALIAS(clone_node, domxml_clone_node, NULL) + PHP_FALIAS(replace_node, domxml_replace_node, NULL) PHP_FALIAS(is_blank_node, domxml_is_blank_node, NULL) {NULL, NULL, NULL} }; @@ -553,7 +560,7 @@ { zval *wrapper; - if (! found) { + if (found) { *found = 0; } @@ -565,7 +572,8 @@ if ((wrapper = (zval *) xpath_object_get_data((void *) obj))) { zval_add_ref(&wrapper); - *found = 1; + if (found) + *found = 1; return wrapper; } @@ -660,7 +668,7 @@ zval *wrapper; int rsrc_type; - if (! found) { + if (found) { *found = 0; } @@ -672,7 +680,8 @@ if ((wrapper = (zval *) xpath_context_get_data((void *) obj))) { zval_add_ref(&wrapper); - *found = 1; + if (found) + *found = 1; return wrapper; } @@ -746,7 +755,7 @@ char *content; int rsrc_type; - if (! found) { + if (found) { *found = 0; } @@ -758,7 +767,8 @@ if ((wrapper = (zval *) dom_object_get_data((void *) obj))) { zval_add_ref(&wrapper); - *found = 1; + if (found) + *found = 1; return wrapper; } @@ -780,10 +790,10 @@ { xmlNodePtr nodep = obj; object_init_ex(wrapper, domxmltext_class_entry); + add_property_long(wrapper, "type", Z_TYPE_P(nodep)); rsrc_type = le_domxmltextp; content = xmlNodeGetContent(nodep); if (content) { - add_property_long(wrapper, "type", Z_TYPE_P(nodep)); add_property_stringl(wrapper, "content", (char *) content, strlen(content), 1); } break; @@ -793,6 +803,7 @@ { xmlNodePtr nodep = obj; object_init_ex(wrapper, domxmlcomment_class_entry); + add_property_long(wrapper, "type", Z_TYPE_P(nodep)); rsrc_type = le_domxmlcommentp; content = xmlNodeGetContent(nodep); if (content) @@ -804,6 +815,7 @@ { xmlNodePtr nodep = obj; object_init_ex(wrapper, domxmlpi_class_entry); + add_property_long(wrapper, "type", Z_TYPE_P(nodep)); rsrc_type = le_domxmlpip; content = xmlNodeGetContent(nodep); add_property_stringl(wrapper, "target", (char *) nodep->name, strlen(nodep->name), 1); @@ -816,6 +828,7 @@ { xmlNodePtr nodep = obj; object_init_ex(wrapper, domxmlentityref_class_entry); + add_property_long(wrapper, "type", Z_TYPE_P(nodep)); rsrc_type = le_domxmlentityrefp; content = xmlNodeGetContent(nodep); add_property_stringl(wrapper, "name", (char *) nodep->name, strlen(nodep->name), 1); @@ -827,8 +840,8 @@ { xmlNodePtr nodep = obj; object_init_ex(wrapper, domxmlnode_class_entry); - rsrc_type = le_domxmlnodep; add_property_long(wrapper, "type", Z_TYPE_P(nodep)); + rsrc_type = le_domxmlnodep; add_property_stringl(wrapper, "name", (char *) nodep->name, strlen(nodep->name), 1); if (Z_TYPE_P(obj) == XML_ENTITY_REF_NODE) { content = xmlNodeGetContent(nodep); @@ -842,6 +855,7 @@ { xmlAttrPtr attrp = (xmlAttrPtr) obj; object_init_ex(wrapper, domxmlattr_class_entry); + add_property_long(wrapper, "type", Z_TYPE_P(attrp)); rsrc_type = le_domxmlattrp; add_property_stringl(wrapper, "name", (char *) attrp->name, strlen(attrp->name), 1); content = xmlNodeGetContent((xmlNodePtr) attrp); @@ -854,6 +868,7 @@ { xmlDocPtr docp = (xmlDocPtr) obj; object_init_ex(wrapper, domxmldoc_class_entry); + add_property_long(wrapper, "type", Z_TYPE_P(docp)); rsrc_type = le_domxmldocp; if (docp->name) add_property_stringl(wrapper, "name", (char *) docp->name, strlen(docp->name), 1); @@ -877,6 +892,7 @@ { xmlDtdPtr dtd = (xmlDtdPtr) obj; object_init_ex(wrapper, domxmldtd_class_entry); + add_property_long(wrapper, "type", Z_TYPE_P(dtd)); rsrc_type = le_domxmldtdp; if (dtd->ExternalID) add_property_string(wrapper, "publicId", (char *) dtd->ExternalID, 1); @@ -891,10 +907,10 @@ { xmlNodePtr nodep = obj; object_init_ex(wrapper, domxmlcdata_class_entry); + add_property_long(wrapper, "type", Z_TYPE_P(nodep)); rsrc_type = le_domxmlcdatap; content = xmlNodeGetContent(nodep); if (content) { - add_property_long(wrapper, "type", Z_TYPE_P(nodep)); add_property_stringl(wrapper, "content", (char *) content, strlen(content), 1); } break; @@ -1205,6 +1221,30 @@ } /* }}} */ +/* {{{ proto object domxml_text_node(string content) + Creates node */ +PHP_FUNCTION(domxml_text_node) +{ + zval *rv; + xmlNode *node; + int ret, content_len; + char *content; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &content, &content_len) == FAILURE) { + return; + } + + node = xmlNewTextLen(content, content_len); + if (!node) { + RETURN_FALSE; + } + + DOMXML_RET_OBJ(rv, node, &ret); +} +/* }}} */ + + + /* {{{ proto object domxml_node_name(void) Returns name of node */ PHP_FUNCTION(domxml_node_name) @@ -1328,7 +1368,7 @@ } /* }}} */ -/* {{{ proto bool domxml_clone_node(void) +/* {{{ proto object domxml_clone_node(bool recursive = false) Clones a node */ PHP_FUNCTION(domxml_clone_node) { @@ -1352,6 +1392,27 @@ } /* }}} */ +/* {{{ proto bool domxml_replace_node(int domnode) + Replaces a node ("this" will replace the old node as passed in domnode) */ +PHP_FUNCTION(domxml_replace_node) +{ + zval *rv, *zold; + zval *id; + xmlNode *n, *old; + + DOMXML_PARAM_TWO(n, id, le_domxmlnodep, "o", &zold, &rv); + DOMXML_GET_OBJ(old, zold, le_domxmlnodep); + + old = xmlReplaceNode(old, n); + if (!old) { + RETURN_FALSE; + } + + RETURN_TRUE; +} +/* }}} */ + + /* {{{ proto object domxml_node_first_child(void) Returns first child from list of children */ PHP_FUNCTION(domxml_node_first_child) @@ -1593,8 +1654,6 @@ DOMXML_NO_ARGS(); xmlUnlinkNode(nodep); - xmlFreeNode(nodep); - zval_dtor(id); /* This is not enough because the children won't be deleted */ RETURN_TRUE; } /* }}} */ @@ -1604,7 +1663,8 @@ PHP_FUNCTION(domxml_node_add_child) { zval *id, *rv, *node; - xmlNodePtr child, nodep; + xmlNodePtr child, nodep, retnode; + int type; int ret; DOMXML_GET_THIS_OBJ(nodep, id, le_domxmlnodep); @@ -1615,14 +1675,53 @@ DOMXML_GET_OBJ(child, node, le_domxmlnodep); - child = xmlAddChild(nodep, child); + /* Note this comment from libxml2::tree.c in xmlAddChild(): + * + * // If cur is a TEXT node, merge its content with adjacent TEXT nodes + * // cur is then freed. + * + * (cur is our "child" variable.) + * Because of this behaviour in libxml2 we have to unlink a TEXT node from + * our le_domxmlnodep before performing xmlAddChild() + * We get wrapper and handle in every case, b/c the TEXT node's to not have to be + * coalesced, which makes the handling a bit hackish: + * - remove a text node, always, b/c we cannot use the possible free'd memory + * - readd the node in case it has not been coalesced + * + * BEWARE! the current php CVS (as of 2002-02-10) uses xmlCopyNode() as a solution. + * but this is not the best solution either, because your PHP code won't be able to + * freely store copies of a nodeID. b/c it will be rendered invalid after each use of ->add_child() + */ + if (child->type == XML_TEXT_NODE) { + zval **handle, *wrapper; + + wrapper = dom_object_get_data(child); + if (wrapper) { + if (zend_hash_index_find(Z_OBJPROP_P(wrapper), 0, (void **)&handle) == FAILURE) { + php_error(E_WARNING, "%s() underlying object missing", get_active_function_name(TSRMLS_C)); + } + else + zend_list_delete(Z_LVAL_PP(handle)); + } + } - if (NULL == child) { + + xmlUnlinkNode(child); + retnode = xmlAddChild(nodep, child); + + if (NULL == retnode) { php_error(E_WARNING, "%s() couldn't add child", get_active_function_name(TSRMLS_C)); RETURN_FALSE; } - DOMXML_RET_OBJ(rv, child, &ret); + /* check, if we have to readd the TEXT node to le_domxmlnodep + */ + if (retnode == child && child->type == XML_TEXT_NODE) { + zval *wrapper; + wrapper = php_domobject_new(child, &ret TSRMLS_CC); + } + + DOMXML_RET_OBJ(rv, retnode, &ret); } /* }}} */ @@ -2457,6 +2556,54 @@ DOMXML_RET_OBJ(rv, nodep, &ret); } /* }}} */ + +/* {{{ proto bool domxml_get_root(int domnode) + Gets root node of document */ +PHP_FUNCTION(domxml_get_root) +{ + zval *id, *rv; + xmlDoc *docp; + xmlNode *root; + int ret; + + DOMXML_PARAM_NONE(docp, id, le_domxmldocp); + + if (!root) { + RETURN_FALSE; + } + + root = xmlDocGetRootElement(docp); + if (!root) { + RETURN_FALSE; + } + + DOMXML_RET_OBJ(rv, root, &ret); +} +/* }}} */ + + +/* {{{ proto bool domxml_set_root(int domnode) + Sets root node of document */ +PHP_FUNCTION(domxml_set_root) +{ + zval *id, *rv, *node; + xmlDoc *docp; + xmlNode *root; + + DOMXML_PARAM_TWO(docp, id, le_domxmldocp, "o", &node, &rv); + DOMXML_GET_OBJ(root, node, le_domxmlnodep); + + if (!root) { + RETURN_FALSE; + } + + xmlDocSetRootElement(docp, root); + + RETURN_TRUE; +} +/* }}} */ + + /* {{{ proto object domxml_new_xmldoc(string version) Creates new xmldoc */ --- php-4.1.1/ext/domxml/php_domxml.h.orig Tue Jan 29 15:02:52 2002 +++ php-4.1.1/ext/domxml/php_domxml.h Mon Feb 11 03:38:05 2002 @@ -56,6 +56,8 @@ PHP_FUNCTION(domxml_doc_create_entity_reference); PHP_FUNCTION(domxml_doc_imported_node); PHP_FUNCTION(domxml_add_root); +PHP_FUNCTION(domxml_get_root); +PHP_FUNCTION(domxml_set_root); PHP_FUNCTION(domxml_intdtd); PHP_FUNCTION(domxml_dumpmem); @@ -87,7 +89,9 @@ PHP_FUNCTION(domxml_node_parent); PHP_FUNCTION(domxml_node_prefix); PHP_FUNCTION(domxml_node); +PHP_FUNCTION(domxml_text_node); PHP_FUNCTION(domxml_clone_node); +PHP_FUNCTION(domxml_replace_node); PHP_FUNCTION(domxml_node_unlink_node); PHP_FUNCTION(domxml_node_new_child); PHP_FUNCTION(domxml_node_set_content);