diff options
author | Uwe Steinmann <steinm@php.net> | 2000-03-02 16:39:50 +0000 |
---|---|---|
committer | Uwe Steinmann <steinm@php.net> | 2000-03-02 16:39:50 +0000 |
commit | ad311c35c75f1f99ab6b505e01fc1305dae05ae3 (patch) | |
tree | aff886fbd41c755551ad9966bf091dc21286bcea | |
parent | 74fba75ca0dd75fc8103299729cef35dcc66dbf3 (diff) | |
download | php-git-ad311c35c75f1f99ab6b505e01fc1305dae05ae3.tar.gz |
- The root node of a xml doc is now an array since it is possible
to have a comment or pi and an element on root level.
-rw-r--r-- | ext/domxml/domxml.c | 184 | ||||
-rw-r--r-- | ext/domxml/php_domxml.h | 1 | ||||
-rw-r--r-- | tests/testdom | 5 |
3 files changed, 139 insertions, 51 deletions
diff --git a/ext/domxml/domxml.c b/ext/domxml/domxml.c index 71bd292e89..6984b7aaba 100644 --- a/ext/domxml/domxml.c +++ b/ext/domxml/domxml.c @@ -55,7 +55,7 @@ static zend_function_entry php_domxml_functions[] = { static zend_function_entry php_domxmldoc_class_functions[] = { - PHP_FALIAS(root, domxml_root, NULL) + PHP_FALIAS(root, domxml_children, NULL) PHP_FALIAS(add_root, domxml_add_root, NULL) PHP_FALIAS(dtd, domxml_intdtd, NULL) PHP_FALIAS(dumpmem, domxml_dumpmem, NULL) @@ -66,10 +66,6 @@ static zend_function_entry php_domxmldtd_class_functions[] = { {NULL, NULL, NULL} }; -/* FIXME: If the following list extends 5 entries, then calling - any of the functions results in a segm fault in execute(). - It appears the hash table is somewhat corrupted. -*/ static zend_function_entry php_domxmlnode_class_functions[] = { PHP_FALIAS(lastchild, domxml_lastchild, NULL) PHP_FALIAS(children, domxml_children, NULL) @@ -82,6 +78,11 @@ static zend_function_entry php_domxmlnode_class_functions[] = { {NULL, NULL, NULL} }; +static zend_function_entry php_domxmltestnode_class_functions[] = { + PHP_FE(domxml_test, NULL) + {NULL, NULL, NULL} +}; + static zend_function_entry php_domxmlattr_class_functions[] = { PHP_FALIAS(name, domxml_attrname, NULL) {NULL, NULL, NULL} @@ -91,6 +92,8 @@ static zend_function_entry php_domxmlns_class_functions[] = { {NULL, NULL, NULL} }; +//void domxmltestnode_class_startup(); + zend_module_entry php_domxml_module_entry = { "DOM", php_domxml_functions, PHP_MINIT(domxml), NULL, NULL, NULL, PHP_MINFO(domxml), STANDARD_MODULE_PROPERTIES }; @@ -107,6 +110,8 @@ PHP_MINIT_FUNCTION(domxml) zend_class_entry domxmlattr_class_entry; zend_class_entry domxmlns_class_entry; +// domxmltestnode_class_startup(); + le_domxmldocp = register_list_destructors(xmlFreeDoc, NULL); /* Freeing the document contains freeing the complete tree. Therefore nodes, attributes etc. may not be freed seperately. @@ -144,9 +149,9 @@ PHP_MINIT_FUNCTION(domxml) return SUCCESS; } -#ifdef 0 +#ifdef kk /* {{{ Node Class */ -pval domxmlnode_class_get_property(zend_property_reference *property_reference) +pval domxmltestnode_class_get_property(zend_property_reference *property_reference) { pval result; zend_overloaded_element *overloaded_property; @@ -183,7 +188,7 @@ pval domxmlnode_class_get_property(zend_property_reference *property_reference) } -int domxmlnode_class_set_property(zend_property_reference *property_reference, pval *value) +int domxmltestnode_class_set_property(zend_property_reference *property_reference, pval *value) { zend_overloaded_element *overloaded_property; zend_llist_element *element; @@ -217,7 +222,7 @@ int domxmlnode_class_set_property(zend_property_reference *property_reference, p return 0; } -void domxmlnode_class_call_function(INTERNAL_FUNCTION_PARAMETERS, zend_property_reference *property_reference) +void domxmltestnode_class_call_function(INTERNAL_FUNCTION_PARAMETERS, zend_property_reference *property_reference) { zend_overloaded_element *overloaded_property; zend_llist_element *element; @@ -234,8 +239,21 @@ void domxmlnode_class_call_function(INTERNAL_FUNCTION_PARAMETERS, zend_property_ case OE_IS_OBJECT: printf("Object property: "); break; - case OE_IS_METHOD: + case OE_IS_METHOD: { + pval *object_handle; printf("Overloaded method: "); + PHP_FN(domxml_xmltree)(INTERNAL_FUNCTION_PARAM_PASSTHRU); + if (zend_is_true(return_value)) { + var_reset(object); + return; + } + ALLOC_ZVAL(object_handle); + *object_handle = *return_value; + pval_copy_constructor(object_handle); + INIT_PZVAL(object_handle); + zend_hash_index_update(object->value.obj.properties, 0, &object_handle, sizeof(pval *), NULL); + pval_destructor(&overloaded_property->element); + } } switch (overloaded_property->element.type) { case IS_LONG: @@ -255,20 +273,35 @@ void domxmlnode_class_call_function(INTERNAL_FUNCTION_PARAMETERS, zend_property_ } -void domxmlnode_class_startup() +void domxmltestnode_class_startup() { - zend_class_entry domxmlnode_class_entry; + zend_class_entry domxmltestnode_class_entry; + + INIT_OVERLOADED_CLASS_ENTRY(domxmltestnode_class_entry, "TestNode", + php_domxmltestnode_class_functions, + domxmltestnode_class_call_function, + domxmltestnode_class_get_property, + domxmltestnode_class_set_property); - INIT_OVERLOADED_CLASS_ENTRY(dcomxmlnode_class_entry, "Dom Node", - php_domxmlnode_class_functions, - domxmlnode_class_call_function, - domxmlnode_class_get_property, - domxmlnode_class_set_property); + register_internal_class(&domxmltestnode_class_entry); +} +#endif + +/* {{{ proto string domxml_test(int id) + Unity function for testing */ +PHP_FUNCTION(domxml_test) +{ + zval *id; + + if ((ARG_COUNT(ht) != 1) || getParameters(ht, 1, &id) == FAILURE) + WRONG_PARAM_COUNT; - register_internal_class(&domxmlnode_class_entry); + convert_to_long(id); + RETURN_LONG(id->value.lval); } /* }}} */ -#endif + +/* }}} */ PHP_MINFO_FUNCTION(domxml) { @@ -481,7 +514,8 @@ PHP_FUNCTION(domxml_children) if (ARG_COUNT(ht) == 0) { id = getThis(); if (id) { - if (zend_hash_find(id->value.obj.properties, "node", sizeof("node"), (void **)&tmp) == FAILURE) { + if ((zend_hash_find(id->value.obj.properties, "node", sizeof("node"), (void **)&tmp) == FAILURE) && + (zend_hash_find(id->value.obj.properties, "doc", sizeof("doc"), (void **)&tmp) == FAILURE)) { php_error(E_WARNING, "unable to find my handle property"); RETURN_FALSE; } @@ -497,12 +531,18 @@ PHP_FUNCTION(domxml_children) } nodep = (xmlNode *)zend_list_find(id_to_find, &type); - if (!nodep || type != le_domxmlnodep) { + if (!nodep || (type != le_domxmlnodep && type != le_domxmldocp)) { php_error(E_WARNING, "unable to find identifier (%d)", id_to_find); RETURN_FALSE; } - last = nodep->childs; + /* Even if the nodep is a XML_DOCUMENT_NODE the type is at the + same position. + */ + if(nodep->type == XML_DOCUMENT_NODE) + last = ((xmlDoc *) nodep)->root; + else + last = nodep->childs; if (!last) { RETURN_FALSE; } @@ -673,9 +713,72 @@ PHP_FUNCTION(domxml_attributes) } /* }}} */ +/* {{{ proto string domxml_root([int doc]) + Returns list of children nodes */ +PHP_FUNCTION(domxml_root) +{ + zval *id, **tmp; + int id_to_find; + xmlDoc *nodep; + xmlNode *last; + int type; + int ret; + + if (ARG_COUNT(ht) == 0) { + id = getThis(); + if (id) { + if (zend_hash_find(id->value.obj.properties, "doc", sizeof("doc"), (void **)&tmp) == FAILURE) { + php_error(E_WARNING, "unable to find my handle property"); + RETURN_FALSE; + } + id_to_find = (*tmp)->value.lval; + } else { + RETURN_FALSE; + } + } else if ((ARG_COUNT(ht) != 1) || getParameters(ht, 1, &id) == FAILURE) { + WRONG_PARAM_COUNT; + } else { + convert_to_long(id); + id_to_find = id->value.lval; + } + + nodep = (xmlDoc *)zend_list_find(id_to_find, &type); + if (!nodep || type != le_domxmldocp) { + php_error(E_WARNING, "unable to find identifier (%d)", id_to_find); + RETURN_FALSE; + } + + last = nodep->root; + if (!last) { + RETURN_FALSE; + } + + if (array_init(return_value) == FAILURE) { + RETURN_FALSE; + } + + while(last) { + zval *child; + MAKE_STD_ZVAL(child); + + ret = zend_list_insert(last, le_domxmlnodep); + + /* construct a node object */ + object_init_ex(child, domxmlnode_class_entry_ptr); + add_property_stringl(child, "name", (char *) last->name, strlen(last->name), 1); + if(last->content) + add_property_stringl(child, "content", (char *) last->content, strlen(last->content), 1); + add_property_resource(child, "node", ret); + add_property_long(child, "type", last->type); + zend_hash_next_index_insert(return_value->value.ht, &child, sizeof(zval *), NULL); + last = last->next; + } +} +/* }}} */ + /* {{{ proto string domxml_root([int doc_handle]) Returns root node of document */ -PHP_FUNCTION(domxml_root) +PHP_FUNCTION(domxml_rootold) { zval *id, **tmp; int id_to_find; @@ -1020,9 +1123,7 @@ PHP_FUNCTION(domxml_new_xmldoc) Returns list of namespaces */ static int node_namespace(zval **attributes, xmlNode *nodep) { - zval *children; xmlNs *ns; - int ret; /* Get the children of the current node */ ns = nodep->ns; @@ -1053,13 +1154,14 @@ static int node_namespace(zval **attributes, xmlNode *nodep) return 0; } +static int node_children(zval **children, xmlNode *nodep); + /* {{{ proto string node_attributes([int node]) Returns list of children nodes */ static int node_attributes(zval **attributes, xmlNode *nodep) { zval *children; xmlAttr *attr; - int ret; /* Get the children of the current node */ attr = nodep->properties; @@ -1100,7 +1202,6 @@ static int node_children(zval **children, xmlNode *nodep) { zval *mchildren, *attributes, *namespace; xmlNode *last; - int ret; /* Get the children of the current node */ last = nodep; @@ -1154,7 +1255,6 @@ PHP_FUNCTION(xmltree) zval *proot, *children, *attributes; xmlDoc *docp; xmlNode *root; - int ret, ret1; if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg) == FAILURE) { WRONG_PARAM_COUNT; @@ -1166,13 +1266,10 @@ PHP_FUNCTION(xmltree) if (!docp) { RETURN_FALSE; } -// ret = zend_list_insert(docp, le_domxmldocp); /* construct the document is a php object for return */ object_init_ex(return_value, domxmldoc_class_entry_ptr); -// add_property_resource(return_value, "doc", ret); add_property_stringl(return_value, "version", (char *) docp->version, strlen(docp->version), 1); - zend_list_addref(ret); /* get the root and add as a property to the document */ root = docp->root; @@ -1180,25 +1277,14 @@ PHP_FUNCTION(xmltree) xmlFreeDoc(docp); RETURN_FALSE; } -// ret1 = zend_list_insert(root, le_domxmlnodep); - /* construct an object with some methods */ - MAKE_STD_ZVAL(proot); - object_init_ex(proot, domxmlnode_class_entry_ptr); -// add_property_resource(proot, "node", ret1); - add_property_long(proot, "type", root->type); - add_property_stringl(proot, "name", (char *) root->name, strlen(root->name), 1); - if(root->content) - add_property_stringl(proot, "content", (char *) root->content, strlen(root->content), 1); - - /* Get the array of children of the root and add as property children */ - if(0 == node_children(&children, root->childs)) - zend_hash_update(proot->value.obj.properties, "children", strlen("children")+1, (void *) &children, sizeof(zval *), NULL); - if(0 == node_attributes(&attributes, root)) - zend_hash_update(proot->value.obj.properties, "attributes", strlen("attributes")+1, (void *) &attributes, sizeof(zval *), NULL); - zend_list_addref(ret1); - /* add the new root object to the document */ - zend_hash_update(return_value->value.obj.properties, "root", strlen("root")+1, (void *) &proot, sizeof(zval *), NULL); + /* The root itself maybe an array. Though you may not have two Elements + as root, you may have a comment, pi and and element as root. + Thanks to Paul DuBois for pointing me at this. + */ + if(0 == node_children(&children, root)) + zend_hash_update(return_value->value.obj.properties, "root", strlen("root")+1, (void *) &children, sizeof(zval *), NULL); + xmlFreeDoc(docp); } /* }}} */ diff --git a/ext/domxml/php_domxml.h b/ext/domxml/php_domxml.h index 5bd7ccb44f..cfed9a1a2e 100644 --- a/ext/domxml/php_domxml.h +++ b/ext/domxml/php_domxml.h @@ -67,6 +67,7 @@ PHP_FUNCTION(domxml_new_child); /* Class Attribute methods */ PHP_FUNCTION(domxml_attrname); +PHP_FUNCTION(domxml_test); #else #define php_domxml_module_ptr NULL #endif /* HAVE_DOMXML */ diff --git a/tests/testdom b/tests/testdom index 53aa75c657..2c64f3de6c 100644 --- a/tests/testdom +++ b/tests/testdom @@ -74,12 +74,13 @@ if(!$dom = xmldoc($xmlstr)) { echo "XML Version: ".$dom->version."\n"; $dtd = $dom->dtd(); $rootnode = $dom->root(); -output_node($rootnode); +foreach($rootnode as $root) + output_node($root); /* This one creates a dom tree made of php objects */ echo "Test 2: creating a tree with php objects\n"; $dom = xmltree($xmlstr); -$dom->root->name = "section"; +//$dom->root->name = "section"; var_dump($dom); echo $dom->root->name; echo "\n"; |