diff options
author | Uwe Steinmann <steinm@php.net> | 2000-02-10 15:24:13 +0000 |
---|---|---|
committer | Uwe Steinmann <steinm@php.net> | 2000-02-10 15:24:13 +0000 |
commit | 992e808451faa8351586468093bb71f4061fd902 (patch) | |
tree | b70962b035b025f99cd100e1a5c1de4877eb12a2 | |
parent | e79c87aca03e5356007c00da3c8de35e92d55f32 (diff) | |
download | php-git-992e808451faa8351586468093bb71f4061fd902.tar.gz |
- added funktion xmltree(), renamed dom() to xmldoc() and domfile()
to xmldocfile().
- testdom covers most of the functionality
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | ext/domxml/domxml.c | 191 | ||||
-rw-r--r-- | ext/domxml/php_domxml.h | 4 | ||||
-rw-r--r-- | tests/testdom | 24 |
4 files changed, 145 insertions, 75 deletions
@@ -2,6 +2,7 @@ PHP 4.0 NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ?? ????, Version 4.0 Beta 4 +- Much more work on domxml. Build xml tree, create xml doc works (Uwe) - Made foreach() work on objects. (Thies, Zend library) - Added domxml extension based on libxml, still little functionality (Uwe) - Fixed memory corruption in fgetss(), strip_tags() and gzgetss() (Zeev) diff --git a/ext/domxml/domxml.c b/ext/domxml/domxml.c index 43b6659569..9f8fd295e9 100644 --- a/ext/domxml/domxml.c +++ b/ext/domxml/domxml.c @@ -34,11 +34,9 @@ static zend_class_entry *domxmlnode_class_entry_ptr; static zend_class_entry *domxmlattr_class_entry_ptr; static zend_function_entry php_domxml_functions[] = { - PHP_FE(getdom, NULL) - PHP_FE(getdomfile, NULL) + PHP_FE(xmldoc, NULL) + PHP_FE(xmldocfile, NULL) PHP_FE(xmltree, NULL) - PHP_FALIAS(dom, getdom, NULL) - PHP_FALIAS(domfile, getdomfile, NULL) PHP_FE(domxml_root, NULL) PHP_FE(domxml_addroot, NULL) PHP_FE(domxml_dumpmem, NULL) @@ -91,6 +89,9 @@ zend_module_entry php_domxml_module_entry = { "DOM", php_domxml_functions, PHP_MINIT(domxml), NULL, NULL, NULL, PHP_MINFO(domxml), STANDARD_MODULE_PROPERTIES }; +void _free_node(xmlNode *tmp) { +//fprintf(stderr, "Freeing node: %s\n", tmp->name); +} PHP_MINIT_FUNCTION(domxml) { @@ -102,9 +103,10 @@ PHP_MINIT_FUNCTION(domxml) le_domxmldocp = register_list_destructors(xmlFreeDoc, NULL); /* Freeing the document contains freeing the complete tree. Therefore nodes, attributes etc. may not be freed seperately. - le_domxmlnodep = register_list_destructors(xmlFreeNode, NULL); - le_domxmlattrp = register_list_destructors(xmlFreeProp, NULL); */ + le_domxmlnodep = register_list_destructors(_free_node, NULL); + le_domxmlattrp = register_list_destructors(NULL, NULL); + INIT_CLASS_ENTRY(domxmldoc_class_entry, "Dom document", php_domxmldoc_class_functions); @@ -143,7 +145,7 @@ PHP_MINFO_FUNCTION(domxml) Returns list of attribute objects */ PHP_FUNCTION(domxml_attrname) { - pval *id, **tmp; + zval *id, **tmp; int id_to_find; xmlNode *nodep; xmlAttr *attr; @@ -178,12 +180,21 @@ PHP_FUNCTION(domxml_attrname) if (!attr) { RETURN_FALSE; } + + if (array_init(return_value) == FAILURE) { + RETURN_FALSE; + } + while(attr) { + zval *pattr; ret = zend_list_insert(attr, le_domxmlattrp); /* construct an object with some methods */ - object_init_ex(return_value, domxmlattr_class_entry_ptr); - add_property_long(return_value, "attribute", ret); + object_init_ex(pattr, domxmlattr_class_entry_ptr); + add_property_resource(pattr, "attribute", ret); + add_property_stringl(pattr, "name", (char *) attr->name, strlen(attr->name), 1); + add_property_stringl(pattr, "value", (char *) attr->val->content, strlen(attr->val->content), 1); + zend_hash_next_index_insert(return_value->value.ht, &pattr, sizeof(zval *), NULL); attr = attr->next; } } @@ -193,7 +204,7 @@ PHP_FUNCTION(domxml_attrname) Creates node */ PHP_FUNCTION(domxml_node) { - pval *arg; + zval *arg; xmlNode *node; int ret; @@ -210,7 +221,7 @@ PHP_FUNCTION(domxml_node) /* construct an object with some methods */ object_init_ex(return_value, domxmlnode_class_entry_ptr); - add_property_long(return_value, "node", ret); + add_property_resource(return_value, "node", ret); add_property_long(return_value, "type", node->type); add_property_stringl(return_value, "name", (char *) node->name, strlen(node->name), 1); if(node->content) @@ -223,7 +234,7 @@ PHP_FUNCTION(domxml_node) Read directory entry from dir_handle */ PHP_FUNCTION(domxml_lastchild) { - pval *id, **tmp; + zval *id, **tmp; int id_to_find; xmlNode *nodep, *last; int type; @@ -262,7 +273,7 @@ PHP_FUNCTION(domxml_lastchild) /* construct an object with some methods */ object_init_ex(return_value, domxmlnode_class_entry_ptr); - add_property_long(return_value, "node", ret); + add_property_resource(return_value, "node", ret); add_property_long(return_value, "type", last->type); add_property_stringl(return_value, "name", (char *) last->name, strlen(last->name), 1); if(last->content) @@ -274,7 +285,7 @@ PHP_FUNCTION(domxml_lastchild) Returns parent of node */ PHP_FUNCTION(domxml_parent) { - pval *id, **tmp; + zval *id, **tmp; int id_to_find; xmlNode *nodep, *last; int type; @@ -313,7 +324,7 @@ PHP_FUNCTION(domxml_parent) /* construct an object with some methods */ object_init_ex(return_value, domxmlnode_class_entry_ptr); - add_property_long(return_value, "node", ret); + add_property_resource(return_value, "node", ret); add_property_long(return_value, "type", last->type); add_property_stringl(return_value, "name", (char *) last->name, strlen(last->name), 1); if(last->content) @@ -325,7 +336,7 @@ PHP_FUNCTION(domxml_parent) Returns list of children nodes */ PHP_FUNCTION(domxml_children) { - pval *id, **tmp; + zval *id, **tmp; int id_to_find; xmlNode *nodep, *last; int type; @@ -375,7 +386,7 @@ PHP_FUNCTION(domxml_children) 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_long(child, "node", ret); + 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; @@ -387,7 +398,7 @@ PHP_FUNCTION(domxml_children) Returns value of given attribute */ PHP_FUNCTION(domxml_getattr) { - pval *id, *arg1, **tmp; + zval *id, *arg1, **tmp; int id_to_find; xmlNode *nodep; char *value; @@ -432,7 +443,7 @@ PHP_FUNCTION(domxml_getattr) Sets value of given attribute */ PHP_FUNCTION(domxml_setattr) { - pval *id, *arg1, *arg2, **tmp; + zval *id, *arg1, *arg2, **tmp; int id_to_find; xmlNode *nodep; xmlAttr *attr; @@ -479,7 +490,7 @@ PHP_FUNCTION(domxml_setattr) Returns list of attributes of node */ PHP_FUNCTION(domxml_attributes) { - pval *id, **tmp; + zval *id, **tmp; int id_to_find; xmlNode *nodep; xmlAttr *attr; @@ -529,7 +540,7 @@ PHP_FUNCTION(domxml_attributes) Returns root node of document */ PHP_FUNCTION(domxml_root) { - pval *id, **tmp; + zval *id, **tmp; int id_to_find; xmlDoc *docp; xmlNode *node; @@ -568,7 +579,7 @@ PHP_FUNCTION(domxml_root) /* construct an object with some methods */ object_init_ex(return_value, domxmlnode_class_entry_ptr); - add_property_long(return_value, "node", ret); + add_property_resource(return_value, "node", ret); add_property_long(return_value, "type", node->type); add_property_stringl(return_value, "name", (char *) node->name, strlen(node->name), 1); if(node->content) @@ -581,7 +592,7 @@ PHP_FUNCTION(domxml_root) Returns DTD of document */ PHP_FUNCTION(domxml_intdtd) { - pval *id, **tmp; + zval *id, **tmp; int id_to_find; xmlDoc *docp; xmlDtd *dtd; @@ -620,7 +631,7 @@ PHP_FUNCTION(domxml_intdtd) /* construct an object with some methods */ object_init_ex(return_value, domxmldtd_class_entry_ptr); - add_property_long(return_value, "dtd", ret); + add_property_resource(return_value, "dtd", ret); if(dtd->ExternalID) add_property_string(return_value, "extid", (char *) dtd->ExternalID, 1); add_property_string(return_value, "sysid", (char *) dtd->SystemID, 1); @@ -633,11 +644,11 @@ PHP_FUNCTION(domxml_intdtd) Dumps document into string */ PHP_FUNCTION(domxml_dumpmem) { - pval *id, **tmp; + zval *id, **tmp; int id_to_find; xmlDoc *docp; - char *mem; -// xmlChar *mem; +// char *mem; + xmlChar *mem; int size; int type; @@ -673,11 +684,11 @@ PHP_FUNCTION(domxml_dumpmem) } /* }}} */ -/* {{{ proto class dom(string xmldoc) +/* {{{ proto class xmldoc(string xmldoc) Creates dom object of xml document */ -PHP_FUNCTION(getdom) +PHP_FUNCTION(xmldoc) { - pval *arg; + zval *arg; xmlDoc *docp; int ret; @@ -694,17 +705,17 @@ PHP_FUNCTION(getdom) /* construct an object with some methods */ object_init_ex(return_value, domxmldoc_class_entry_ptr); - add_property_long(return_value, "doc", ret); + add_property_resource(return_value, "doc", ret); add_property_stringl(return_value, "version", (char *) docp->version, strlen(docp->version), 1); zend_list_addref(ret); } /* }}} */ -/* {{{ proto class dom(string filename) +/* {{{ proto class xmldocfile(string filename) Creates dom object of xml document in file*/ -PHP_FUNCTION(getdomfile) +PHP_FUNCTION(xmldocfile) { - pval *arg; + zval *arg; xmlDoc *docp; int ret; @@ -721,7 +732,7 @@ PHP_FUNCTION(getdomfile) /* construct an object with some methods */ object_init_ex(return_value, domxmldoc_class_entry_ptr); - add_property_long(return_value, "doc", ret); + add_property_resource(return_value, "doc", ret); add_property_stringl(return_value, "version", (char *) docp->version, strlen(docp->version), 1); zend_list_addref(ret); } @@ -731,7 +742,7 @@ PHP_FUNCTION(getdomfile) Adds child node to parent node */ PHP_FUNCTION(domxml_newchild) { - pval *id, *name, *content, **tmp; + zval *id, *name, *content, **tmp; int id_to_find; xmlNode *child, *nodep; int type; @@ -776,7 +787,7 @@ PHP_FUNCTION(domxml_newchild) /* construct an object with some methods */ object_init_ex(return_value, domxmlnode_class_entry_ptr); - add_property_long(return_value, "node", ret); + add_property_resource(return_value, "node", ret); add_property_long(return_value, "type", child->type); add_property_stringl(return_value, "name", (char *) child->name, strlen(child->name), 1); if(content->value.str.val) @@ -789,7 +800,7 @@ PHP_FUNCTION(domxml_newchild) Adds root node to document */ PHP_FUNCTION(domxml_addroot) { - pval *id, *name, **tmp; + zval *id, *name, **tmp; int id_to_find; xmlDoc *docp; xmlNode *node; @@ -832,7 +843,7 @@ PHP_FUNCTION(domxml_addroot) /* construct an object with some methods */ object_init_ex(return_value, domxmlnode_class_entry_ptr); - add_property_long(return_value, "node", ret); + add_property_resource(return_value, "node", ret); add_property_long(return_value, "type", node->type); add_property_stringl(return_value, "name", (char *) node->name, strlen(node->name), 1); if(node->content) @@ -845,7 +856,7 @@ PHP_FUNCTION(domxml_addroot) Creates new xmldoc */ PHP_FUNCTION(domxml_newxmldoc) { - pval *arg; + zval *arg; xmlDoc *docp; int ret; @@ -862,7 +873,7 @@ PHP_FUNCTION(domxml_newxmldoc) /* construct an object with some methods */ object_init_ex(return_value, domxmldoc_class_entry_ptr); - add_property_long(return_value, "doc", ret); + add_property_resource(return_value, "doc", ret); add_property_stringl(return_value, "version", (char *) docp->version, strlen(docp->version), 1); zend_list_addref(ret); } @@ -870,42 +881,84 @@ PHP_FUNCTION(domxml_newxmldoc) /* {{{ proto string domxml_children([int node]) Returns list of children nodes */ -int node_children(pval **children, xmlNode *nodep) +static int node_attributes(zval **attributes, xmlNode *nodep) { -#if 0 - pval *id, **tmp, *mchildren; - int id_to_find; - xmlNode *nodep, *last; - int type; + xmlAttr *attr; int ret; - + + /* Get the children of the current node */ + attr = nodep->properties; + if (!attr) { + return -1; + } + + /* create an php array for the children */ + MAKE_STD_ZVAL(*attributes); + if (array_init(*attributes) == FAILURE) { + return -1; + } + + while(attr) { + zval *pattr; + MAKE_STD_ZVAL(pattr); + ret = zend_list_insert(attr, le_domxmlattrp); + + /* construct an object with some methods */ + object_init_ex(pattr, domxmlattr_class_entry_ptr); + add_property_resource(pattr, "attribute", ret); + add_property_stringl(pattr, "name", (char *) attr->name, strlen(attr->name), 1); + add_property_stringl(pattr, "value", (char *) attr->val->content, strlen(attr->val->content), 1); + zend_hash_next_index_insert((*attributes)->value.ht, &pattr, sizeof(zval *), NULL); + attr = attr->next; + } + return 0; +} + +/* {{{ proto string domxml_children([int node]) + Returns list of children nodes */ +static int node_children(zval **children, xmlNode *nodep) +{ + zval *mchildren, *attributes; + xmlNode *last; + int ret; + + /* Get the children of the current node */ last = nodep->childs; if (!last) { - RETURN_FALSE; + return -1; } + /* create an php array for the children */ + MAKE_STD_ZVAL(*children); if (array_init(*children) == FAILURE) { return -1; } while(last) { zval *child; - MAKE_STD_ZVAL(child); + /* Each child is a node object */ + MAKE_STD_ZVAL(child); ret = zend_list_insert(last, le_domxmlnodep); - /* construct a node object */ + /* construct a node object for each child */ 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_long(child, "node", ret); + add_property_resource(child, "node", ret); add_property_long(child, "type", last->type); - zend_hash_next_index_insert(children->value.ht, &child, sizeof(zval *), NULL); - node_children(&mchildren, last); + /* Add the node object to the array of children */ + zend_hash_next_index_insert((*children)->value.ht, &child, sizeof(zval *), NULL); + /* Get recursively the children of the current node */ + if(!node_children(&mchildren, last)) + zend_hash_update(child->value.obj.properties, "children", strlen("children")+1, (void *) &mchildren, sizeof(zval *), NULL); + if(!node_attributes(&attributes, last)) + zend_hash_update(child->value.obj.properties, "attributes", strlen("attributes")+1, (void *) &attributes, sizeof(zval *), NULL); + last = last->next; } -#endif + return 0; } /* }}} */ @@ -913,10 +966,10 @@ int node_children(pval **children, xmlNode *nodep) Create a tree of php objects from an xml document */ PHP_FUNCTION(xmltree) { - pval *arg; - pval *proot; + zval *arg; + zval *proot, *children, *attributes; xmlDoc *docp; - xmlNode *root, *node; + xmlNode *root; int ret, ret1; if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg) == FAILURE) { @@ -924,35 +977,43 @@ PHP_FUNCTION(xmltree) } convert_to_string(arg); + /* Create a new xml document */ docp = xmlParseMemory(arg->value.str.val, arg->value.str.len); if (!docp) { RETURN_FALSE; } ret = zend_list_insert(docp, le_domxmldocp); - /* construct an object with some methods */ + /* construct the document is a php object for return */ object_init_ex(return_value, domxmldoc_class_entry_ptr); - add_property_long(return_value, "doc", ret); + 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; if (!root) { RETURN_FALSE; } ret1 = zend_list_insert(root, le_domxmlnodep); +// add_property_resource(return_value, "root", ret1); - add_property_long(return_value, "root", ret); /* construct an object with some methods */ + MAKE_STD_ZVAL(proot); object_init_ex(proot, domxmlnode_class_entry_ptr); - add_property_long(proot, "node", ret1); + 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(return_value, "content", (char *) root->content, strlen(root->content), 1); + 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)) + 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); } /* }}} */ diff --git a/ext/domxml/php_domxml.h b/ext/domxml/php_domxml.h index bee87423a3..a479d3f410 100644 --- a/ext/domxml/php_domxml.h +++ b/ext/domxml/php_domxml.h @@ -43,8 +43,8 @@ extern zend_module_entry php_domxml_module_entry; /* directory functions */ extern PHP_MINIT_FUNCTION(domxml); extern PHP_MINFO_FUNCTION(domxml); -PHP_FUNCTION(getdom); -PHP_FUNCTION(getdomfile); +PHP_FUNCTION(xmldoc); +PHP_FUNCTION(xmldocfile); PHP_FUNCTION(xmltree); PHP_FUNCTION(domxml_newxmldoc); diff --git a/tests/testdom b/tests/testdom index c668813031..e8e01a94bd 100644 --- a/tests/testdom +++ b/tests/testdom @@ -37,8 +37,8 @@ function list_attr($node) { $xmlstr = "<?xml version='1.0'?> <!DOCTYPE chapter SYSTEM '/share/sgml/Norman_Walsh/db3xml10/db3xml10.dtd'> <chapter language='en'><title language='en'>Title</title> -<para language='en'> -<informaltable language='en'> +<para language='ge'> +<informaltable language='sp'> <tgroup cols='3'> <tbody> <row><entry>a1</entry><entry morerows='1'>b1</entry><entry>c1</entry></row> @@ -50,17 +50,25 @@ $xmlstr = "<?xml version='1.0'?> </para> </chapter> "; -$dom = dom($xmlstr); +/* The following code traverses the xml tree node by node + by using the methods of the xmlnode object +*/ +echo "Test 1: accessing single nodes from php\n"; +$dom = xmldoc($xmlstr); echo "XML Version: ".$dom->version."\n"; $dtd = $dom->dtd(); $rootnode = $dom->root(); -/* The following line causes a segm fault if more than 5 methods are in - class node, see ext/domxml/domxml.c */ -$attr = $rootnode->getattr("language"); - -/* if the above weren't there, php will probably crash somewhere after here */ output_node($rootnode); +/* This one creates a dom tree made of php objects */ +echo "Test 2: creating a tree with php objects\n"; +$dom = xmltree($xmlstr); +var_dump($dom); +echo $dom->root->name; +echo "\n"; + +/* The following builds a xml document from scratch */ +echo "Test 3: building a xml document from scratch\n"; $doc = newxmldoc("1.0"); $root = $doc->addroot("HTML"); $head = $root->newchild("HEAD", ""); |