Index: ext/domxml/php_domxml.c =================================================================== RCS file: /repository/php4/ext/domxml/php_domxml.c,v retrieving revision 1.133 diff -u -r1.133 php_domxml.c --- ext/domxml/php_domxml.c 4 Apr 2002 12:16:48 -0000 1.133 +++ ext/domxml/php_domxml.c 13 Apr 2002 11:05:17 -0000 @@ -203,6 +203,7 @@ PHP_FE(domxml_node_has_attributes, 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_node_get_content, NULL) @@ -262,6 +263,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(set_root, domxml_set_root, NULL) + PHP_FALIAS(get_root, domxml_get_root, NULL) PHP_FALIAS(imported_node, domxml_doc_imported_node, NULL) PHP_FALIAS(dtd, domxml_intdtd, NULL) PHP_FALIAS(dumpmem, domxml_dump_mem, NULL) @@ -307,6 +310,7 @@ PHP_FALIAS(next_sibling, domxml_node_next_sibling, NULL) PHP_FALIAS(has_child_nodes, domxml_node_has_child_nodes, NULL) PHP_FALIAS(prefix, domxml_node_prefix, NULL) + PHP_FALIAS(get_path, domxml_node_get_path, NULL) PHP_FALIAS(parent, domxml_node_parent, NULL) PHP_FALIAS(parent_node, domxml_node_parent, NULL) PHP_FALIAS(insert_before, domxml_node_insert_before, NULL) @@ -744,7 +748,7 @@ { zval *wrapper; - *found = 0; + *found = 0; if (!obj) { MAKE_STD_ZVAL(wrapper); @@ -849,7 +853,7 @@ zval *wrapper; int rsrc_type; - *found = 0; + *found = 0; if (!obj) { MAKE_STD_ZVAL(wrapper); @@ -933,7 +937,7 @@ char *content; int rsrc_type; - *found = 0; + *found = 0; if (!obj) { MAKE_STD_ZVAL(wrapper); @@ -1451,6 +1455,34 @@ } /* }}} */ +static void php_textnode_new(INTERNAL_FUNCTION_PARAMETERS, xmlDocPtr docp) +{ + 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; + } + node->doc = docp; + + DOMXML_RET_OBJ(rv, node, &ret); +} + +/* {{{ proto object domxml_text_node(string content) + Creates node */ +PHP_FUNCTION(domxml_text_node) +{ + php_textnode_new(INTERNAL_FUNCTION_PARAM_PASSTHRU, NULL); +} +/* }}} */ + /* {{{ proto object domxml_node_name(void) Returns name of node */ PHP_FUNCTION(domxml_node_name) @@ -1778,6 +1810,26 @@ } /* }}} */ +/* {{{ proto string domxml_node_get_path(void) + Returns the path of the node in the document */ +PHP_FUNCTION(domxml_node_get_path) +{ + zval *id; + xmlNode *nodep; + xmlChar *path; + + DOMXML_GET_THIS_OBJ(nodep, id, le_domxmlnodep); + + DOMXML_NO_ARGS(); + + path = xmlGetNodePath(nodep); + if (!path) { + RETURN_EMPTY_STRING(); + } + RETVAL_STRING((char *)path, 1); + xmlFree(path); +} + /* {{{ proto object domxml_node_parent(void) Returns parent of node */ PHP_FUNCTION(domxml_node_parent) @@ -1873,19 +1925,59 @@ RETURN_FALSE; } +#if 0 if (NULL == (new_child = xmlCopyNode(child, 1))) { php_error(E_WARNING, "%s(): unable to clone node", get_active_function_name(TSRMLS_C)); RETURN_FALSE; } +#endif + + /* 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)); + } + } - child = xmlAddChild(nodep, new_child); + new_child = xmlAddChild(nodep, child); if (NULL == child) { 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 + * because it has not been coalesced and free()d. + */ + if (new_child == child && child->type == XML_TEXT_NODE) { + zval *wrapper; + wrapper = php_domobject_new(child, &ret TSRMLS_CC); + } + + DOMXML_RET_OBJ(rv, new_child, &ret); } /* }}} */ @@ -2622,25 +2714,11 @@ Creates new text node */ PHP_FUNCTION(domxml_doc_create_text_node) { - zval *id, *rv; - xmlNode *node; + zval *id; xmlDocPtr docp; - int ret, content_len; - char *content; DOMXML_GET_THIS_OBJ(docp, id, le_domxmldocp); - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &content, &content_len) == FAILURE) { - return; - } - - node = xmlNewTextLen(content, content_len); - if (!node) { - RETURN_FALSE; - } - node->doc = docp; - - DOMXML_RET_OBJ(rv, node, &ret); + php_textnode_new(INTERNAL_FUNCTION_PARAM_PASSTHRU, docp); } /* }}} */ @@ -3128,6 +3206,47 @@ } /* }}} */ +/* {{{ 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); + + 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_FUNCTION(domxml_new_xmldoc) @@ -3580,7 +3699,7 @@ zval *wrapper; int rsrc_type; - *found = 0; + *found = 0; if (!obj) { MAKE_STD_ZVAL(wrapper); Index: ext/domxml/php_domxml.h =================================================================== RCS file: /repository/php4/ext/domxml/php_domxml.h,v retrieving revision 1.43 diff -u -r1.43 php_domxml.h --- ext/domxml/php_domxml.h 11 Mar 2002 22:37:32 -0000 1.43 +++ ext/domxml/php_domxml.h 13 Apr 2002 11:05:17 -0000 @@ -78,6 +78,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_dump_mem); PHP_FUNCTION(domxml_dump_mem_file); @@ -114,7 +116,9 @@ PHP_FUNCTION(domxml_node_has_child_nodes); PHP_FUNCTION(domxml_node_parent); PHP_FUNCTION(domxml_node_prefix); +PHP_FUNCTION(domxml_node_get_path); PHP_FUNCTION(domxml_node); +PHP_FUNCTION(domxml_text_node); PHP_FUNCTION(domxml_clone_node); PHP_FUNCTION(domxml_node_unlink_node); PHP_FUNCTION(domxml_node_replace_node);