]> granicus.if.org Git - php/commitdiff
implement namednodemap and nodelist
authorRob Richards <rrichards@php.net>
Sat, 29 Nov 2003 20:40:18 +0000 (20:40 +0000)
committerRob Richards <rrichards@php.net>
Sat, 29 Nov 2003 20:40:18 +0000 (20:40 +0000)
fix xsl/dom integration under windows
update tests and examples

14 files changed:
ext/dom/config.m4
ext/dom/document.c
ext/dom/documenttype.c
ext/dom/element.c
ext/dom/examples/dom1.inc
ext/dom/examples/dom1.php
ext/dom/namednodemap.c
ext/dom/node.c
ext/dom/nodelist.c
ext/dom/php_dom.c
ext/dom/php_dom.h
ext/dom/tests/dom001.phpt
ext/dom/tests/dom_test.inc
ext/dom/xml_common.h

index 41699b080771ba151d31cafc350360f90f09b96d..82c97e6bd34ce4fb54f2c1142ccdd617b71e9937 100644 (file)
@@ -22,7 +22,7 @@ if test "$PHP_DOM" != "no" && test "$PHP_LIBXML" != "no"; then
                             documenttype.c domimplementationlist.c entity.c \
                             nodelist.c text.c comment.c domconfiguration.c \
                             domimplementationsource.c entityreference.c \
-                            notation.c xpath.c \
+                            notation.c xpath.c dom_iterators.c \
                             typeinfo.c domerror.c domlocator.c namednodemap.c userdatahandler.c], 
                             $ext_shared)
     PHP_SUBST(DOM_SHARED_LIBADD)
index 8246d891f77c2134f17fbcefef5156d6240c43d0..034b83f3992e7bd370ac46e6907cceed5672127e 100644 (file)
@@ -884,10 +884,10 @@ PHP_FUNCTION(dom_document_get_elements_by_tag_name)
 {
        zval *id;
        xmlDocPtr docp;
-       xmlNodePtr elemp;
        int name_len;
-       dom_object *intern;
+       dom_object *intern, *namednode;
        char *name;
+       xmlChar *local;
 
        DOM_GET_THIS_OBJ(docp, id, xmlDocPtr, intern);
 
@@ -895,10 +895,10 @@ PHP_FUNCTION(dom_document_get_elements_by_tag_name)
                return;
        }
 
-       array_init(return_value);
-       elemp = xmlDocGetRootElement(docp);
-
-       dom_get_elements_by_tag_name_ns_raw(elemp, NULL, name, &return_value, intern TSRMLS_CC);
+       php_dom_create_interator(return_value, DOM_NODELIST TSRMLS_CC);
+       namednode = (dom_object *)zend_objects_get_address(return_value TSRMLS_CC);
+       local = xmlCharStrndup(name, name_len);
+       dom_namednode_iter(intern, 0, namednode, NULL, local, NULL);
 }
 /* }}} end dom_document_get_elements_by_tag_name */
 
@@ -1075,10 +1075,10 @@ PHP_FUNCTION(dom_document_get_elements_by_tag_name_ns)
 {
        zval *id;
        xmlDocPtr docp;
-       xmlNodePtr elemp;
        int uri_len, name_len;
-       dom_object *intern;
+       dom_object *intern, *namednode;
        char *uri, *name;
+       xmlChar *local, *nsuri;
 
        DOM_GET_THIS_OBJ(docp, id, xmlDocPtr, intern);
 
@@ -1086,10 +1086,11 @@ PHP_FUNCTION(dom_document_get_elements_by_tag_name_ns)
                return;
        }
 
-       array_init(return_value);
-       elemp = xmlDocGetRootElement(docp);
-
-       dom_get_elements_by_tag_name_ns_raw(elemp, uri, name, &return_value, intern TSRMLS_CC);
+       php_dom_create_interator(return_value, DOM_NODELIST TSRMLS_CC);
+       namednode = (dom_object *)zend_objects_get_address(return_value TSRMLS_CC);
+       local = xmlCharStrndup(name, name_len);
+       nsuri = xmlCharStrndup(uri, uri_len);
+       dom_namednode_iter(intern, 0, namednode, NULL, local, nsuri);
 }
 /* }}} end dom_document_get_elements_by_tag_name_ns */
 
index cd6af0d0766c1816c20eed90f4f63cdffb469cf5..036e825a6d23b4a08fbf9498d3d3168d9f90c371 100644 (file)
 #if HAVE_LIBXML && HAVE_DOM
 #include "php_dom.h"
 
-typedef struct _nodeIterator nodeIterator;
-struct _nodeIterator {
-       int cur;
-       int index;
-       xmlNode *node;
-};
-
-typedef struct _notationIterator notationIterator;
-struct _notationIterator {
-       int cur;
-       int index;
-       xmlNotation *notation;
-};
-
-static void itemHashScanner (void *payload, void *data, xmlChar *name) {
-       nodeIterator *priv = (nodeIterator *)data;
-
-       if(priv->cur < priv->index) {
-               priv->cur++;
-       } else {
-               if(priv->node == NULL) {
-                       priv->node = (xmlNode *)payload;
-               }
-       }
-}
-
-/* {{{ static xmlEntityPtr create_notation(const xmlChar *name, 
-                               const xmlChar *ExternalID, const xmlChar *SystemID) */
-static xmlNodePtr create_notation(const xmlChar *name, 
-                                                                       const xmlChar *ExternalID, const xmlChar *SystemID) {
-       xmlEntityPtr ret;
-
-       ret = (xmlEntityPtr) xmlMalloc(sizeof(xmlEntity));
-    memset(ret, 0, sizeof(xmlEntity));
-    ret->type = XML_NOTATION_NODE;
-    ret->name = xmlStrdup(name);
-       ret->ExternalID = xmlStrdup(ExternalID);
-       ret->SystemID = xmlStrdup(SystemID);
-       ret->length = 0;
-       ret->content = NULL;
-       ret->URI = NULL;
-       ret->orig = NULL;
-       ret->children = NULL;
-       ret->parent = NULL;
-       ret->doc = NULL;
-       ret->_private = NULL;
-       ret->last = NULL;
-       ret->prev = NULL;
-       return((xmlNodePtr) ret);
-}
-
 /*
 * class domdocumenttype extends domnode 
 *
@@ -120,36 +69,18 @@ int dom_documenttype_entities_read(dom_object *obj, zval **retval TSRMLS_DC)
 {
        xmlDtdPtr doctypep;
        xmlHashTable *entityht;
-       nodeIterator *iter;
-       xmlNode *nodep = NULL;
-       int ret, htsize, index = 0;
+       dom_object *intern;
 
        doctypep = (xmlDtdPtr) dom_object_get_node(obj);
 
-       ALLOC_ZVAL(*retval);
-       array_init(*retval);
+       MAKE_STD_ZVAL(*retval);
+       php_dom_create_interator(*retval, DOM_NAMEDNODEMAP TSRMLS_CC);
 
        entityht = (xmlHashTable *) doctypep->entities;
-       if (entityht) {
-               if ((htsize = xmlHashSize(entityht)) > 0) {
-                       iter = emalloc(sizeof(nodeIterator));
-                       while (index < htsize) {
-                               iter->cur = 0;
-                               iter->index = index;
-                               iter->node = NULL;
-                               xmlHashScan(entityht, itemHashScanner, iter);
-                               index++;
-                               nodep = iter->node;
-                               if (nodep != NULL) {
-                                       zval *child;
-                                       MAKE_STD_ZVAL(child);
-                                       child = php_dom_create_object(nodep, &ret, NULL, child, obj TSRMLS_CC);
-                                       add_assoc_zval(*retval, (char *) nodep->name, child);
-                               }
-                       }
-                       efree(iter);
-               }
-       }
+
+       intern = (dom_object *)zend_objects_get_address(*retval TSRMLS_CC);
+       dom_namednode_iter(obj, XML_ENTITY_NODE, intern, entityht, NULL, NULL);
+
        return SUCCESS;
 }
 
@@ -166,38 +97,14 @@ int dom_documenttype_notations_read(dom_object *obj, zval **retval TSRMLS_DC)
 {
        xmlDtdPtr doctypep;
        xmlHashTable *notationht;
-       notationIterator *iter;
-       xmlNotationPtr notep = NULL;
-       xmlNode *nodep = NULL;
-       int ret, htsize, index = 0;
+       dom_object *intern;
 
        doctypep = (xmlDtdPtr) dom_object_get_node(obj);
+       notationht = (xmlHashTable *) doctypep->notations;
 
-       MAKE_STD_ZVAL(*retval);
-       array_init(*retval);
+       intern = (dom_object *)zend_objects_get_address(*retval TSRMLS_CC);
+       dom_namednode_iter(obj, XML_NOTATION_NODE, intern, notationht, NULL, NULL);
 
-       notationht = (xmlHashTable *) doctypep->notations;
-       if (notationht) {
-               if ((htsize = xmlHashSize(notationht)) > 0) {
-                       iter = emalloc(sizeof(nodeIterator));
-                       while (index < htsize) {
-                               iter->cur = 0;
-                               iter->index = index;
-                               iter->notation = NULL;
-                               xmlHashScan(notationht, itemHashScanner, iter);
-                               index++;
-                               notep = iter->notation;
-                               if (notep != NULL) {
-                                       zval *child;
-                                       nodep = create_notation(notep->name, notep->PublicID, notep->SystemID);
-                                       MAKE_STD_ZVAL(child);
-                                       child = php_dom_create_object(nodep, &ret, NULL, child, obj TSRMLS_CC);
-                                       add_assoc_zval(*retval, (char *) nodep->name, child);
-                               }
-                       }
-                       efree(iter);
-               }
-       }
        return SUCCESS;
 }
 
index 84b01618bd439fcc31b11ffd9667e3872dcf31cf..bd146637e6b530d637569b2b5ad4b33df20bfe96 100644 (file)
@@ -394,8 +394,9 @@ PHP_FUNCTION(dom_element_get_elements_by_tag_name)
        zval *id;
        xmlNodePtr elemp;
        int name_len;
-       dom_object *intern;
+       dom_object *intern, *namednode;
        char *name;
+       xmlChar *local;
 
        DOM_GET_THIS_OBJ(elemp, id, xmlNodePtr, intern);
 
@@ -403,10 +404,10 @@ PHP_FUNCTION(dom_element_get_elements_by_tag_name)
                return;
        }
 
-       array_init(return_value);
-       elemp = elemp->children;
-
-       dom_get_elements_by_tag_name_ns_raw(elemp, NULL, name, &return_value, intern TSRMLS_CC);
+       php_dom_create_interator(return_value, DOM_NODELIST TSRMLS_CC);
+       namednode = (dom_object *)zend_objects_get_address(return_value TSRMLS_CC);
+       local = xmlCharStrndup(name, name_len);
+       dom_namednode_iter(intern, 0, namednode, NULL, local, NULL);
 }
 /* }}} end dom_element_get_elements_by_tag_name */
 
@@ -708,8 +709,10 @@ PHP_FUNCTION(dom_element_get_elements_by_tag_name_ns)
        zval *id;
        xmlNodePtr elemp;
        int uri_len, name_len;
-       dom_object *intern;
+       dom_object *intern, *namednode;
        char *uri, *name;
+       xmlChar *local, *nsuri;
+// xmlHashTable *ht;
 
        DOM_GET_THIS_OBJ(elemp, id, xmlNodePtr, intern);
 
@@ -717,9 +720,12 @@ PHP_FUNCTION(dom_element_get_elements_by_tag_name_ns)
                return;
        }
 
-       array_init(return_value);
+       php_dom_create_interator(return_value, DOM_NODELIST TSRMLS_CC);
+       namednode = (dom_object *)zend_objects_get_address(return_value TSRMLS_CC);
+       local = xmlCharStrndup(name, name_len);
+       nsuri = xmlCharStrndup(uri, uri_len);
+       dom_namednode_iter(intern, 0, namednode, NULL, local, nsuri);
 
-       dom_get_elements_by_tag_name_ns_raw(elemp->children, uri, name, &return_value, intern TSRMLS_CC);
 }
 /* }}} end dom_element_get_elements_by_tag_name_ns */
 
index 96acddc6691cc247a34554017112c6bf76f0259c..792d6f2dbc4818b45a6e5d33964d0487de5d5af7 100644 (file)
@@ -24,7 +24,7 @@ function print_node($node)
 {
   print "Node Name: " . $node->nodeName;
   print "\nNode Type: " . $node->nodeType;
-  $child_count = count($node->childNodes);
+  $child_count = $node->childNodes->length;
   print "\nNum Children: " . $child_count;
   if($child_count <= 1){
     print "\nNode Content: " . $node->nodeValue;
index 8654b19c2f0b1eeac73d5b4386611df2ac285c71..99125a2a37b57d3f532fc88cd904398a09642765 100644 (file)
@@ -60,7 +60,7 @@ $attrs = $rootnode->attributes;
 print_node_list($attrs);
 
 echo "--------- children of an attribute\n";
-$children = current($attrs)->childNodes;
+$children = $attrs->item(0)->childNodes;
 print_node_list($children);
 
 echo "--------- Add child to root\n";
@@ -80,8 +80,8 @@ $children = $rootnode->getElementsByTagName("Silly");
 print_node_list($children);
 
 echo "--------- Unlink Node\n";
-print_node($children[0]);
-$rootnode->removeChild($children[0]);
+print_node($children.item(0));
+$rootnode->removeChild($children.item(0));
 print_node_list($rootnode->childNodes);
 print $dom->savexml();
 
index ada109ad8027e4f89060f277fce4e36b31681579..1e4eefbe23c01800e503bbdb9ab511c2ad5dd129 100644 (file)
@@ -55,8 +55,30 @@ Since:
 */
 int dom_namednodemap_length_read(dom_object *obj, zval **retval TSRMLS_DC)
 {
-       ALLOC_ZVAL(*retval);
-       ZVAL_STRING(*retval, "TEST", 1);
+       dom_nnodemap_object *objmap;
+       xmlAttrPtr curnode;
+       xmlNodePtr nodep;
+       int count = 0;
+
+       objmap = (dom_nnodemap_object *)obj->ptr;
+       if (objmap->ht) {
+               count = xmlHashSize(objmap->ht);
+       } else {
+               nodep = dom_object_get_node(objmap->baseobj);
+               if (nodep) {
+                       curnode = nodep->properties;
+                       if (curnode) {
+                               count++;
+                               while (curnode->next != NULL) {
+                                       count++;
+                                       curnode = curnode->next;
+                               }
+                       }
+               }
+       }
+
+       MAKE_STD_ZVAL(*retval);
+       ZVAL_LONG(*retval, count);
        return SUCCESS;
 }
 
@@ -71,7 +93,44 @@ Since:
 */
 PHP_FUNCTION(dom_namednodemap_get_named_item)
 {
- DOM_NOT_IMPLEMENTED();
+       zval *id, *rv = NULL;
+       int ret, namedlen=0;
+       dom_object *intern;
+       xmlNodePtr itemnode = NULL;
+       char *named;
+
+       dom_nnodemap_object *objmap;
+       xmlNodePtr nodep;
+       xmlNotation *notep = NULL;
+
+       id = getThis();
+       
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &named, &namedlen) == FAILURE) {
+               return;
+       }
+
+       intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
+
+       objmap = (dom_nnodemap_object *)intern->ptr;
+       if (objmap->ht) {
+               if (objmap->nodetype == XML_ENTITY_NODE) {
+                       itemnode = (xmlNodePtr)xmlHashLookup(objmap->ht, named);
+               } else {
+                       notep = (xmlNotation *)xmlHashLookup(objmap->ht, named);
+                       itemnode = create_notation(notep->name, notep->PublicID, notep->SystemID);
+               }
+       } else {
+               nodep = dom_object_get_node(objmap->baseobj);
+               if (nodep) {
+                       itemnode = (xmlNodePtr)xmlHasProp(nodep, named);
+               }
+       }
+
+       if (itemnode) {
+               DOM_RET_OBJ(rv, itemnode, &ret, objmap->baseobj);
+       } else {
+               RETVAL_NULL();
+       }
 }
 /* }}} end dom_namednodemap_get_named_item */
 
@@ -104,7 +163,50 @@ Since:
 */
 PHP_FUNCTION(dom_namednodemap_item)
 {
- DOM_NOT_IMPLEMENTED();
+       zval *id, *rv = NULL;
+       int index, ret;
+       dom_object *intern;
+       xmlNodePtr itemnode = NULL;
+
+       dom_nnodemap_object *objmap;
+       xmlNodePtr nodep, curnode;
+       int count;
+
+       id = getThis();
+       
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &index) == FAILURE) {
+               return;
+       }
+
+       if (index >= 0) {
+               intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
+
+               objmap = (dom_nnodemap_object *)intern->ptr;
+               if (objmap->ht) {
+                       if (objmap->nodetype == XML_ENTITY_NODE) {
+                               itemnode = php_dom_libxml_hash_iter(objmap->ht, index);
+                       } else {
+                               itemnode = php_dom_libxml_notation_iter(objmap->ht, index);
+                       }
+               } else {
+                       nodep = dom_object_get_node(objmap->baseobj);
+                       if (nodep) {
+                               curnode = (xmlNodePtr)nodep->properties;
+                               count = 0;
+                               while (count < index && curnode != NULL) {
+                                       count++;
+                                       curnode = (xmlNodePtr)curnode->next;
+                               }
+                               itemnode = curnode;
+                       }
+               }
+       }
+
+       if (itemnode) {
+               DOM_RET_OBJ(rv, itemnode, &ret, objmap->baseobj);
+       } else {
+               RETVAL_NULL();
+       }
 }
 /* }}} end dom_namednodemap_item */
 
@@ -115,7 +217,44 @@ Since: DOM Level 2
 */
 PHP_FUNCTION(dom_namednodemap_get_named_item_ns)
 {
- DOM_NOT_IMPLEMENTED();
+       zval *id, *rv = NULL;
+       int ret, namedlen=0, urilen=0;
+       dom_object *intern;
+       xmlNodePtr itemnode = NULL;
+       char *uri, *named;
+
+       dom_nnodemap_object *objmap;
+       xmlNodePtr nodep;
+       xmlNotation *notep = NULL;
+
+       id = getThis();
+       
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &uri, &urilen, &named, &namedlen) == FAILURE) {
+               return;
+       }
+
+       intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
+
+       objmap = (dom_nnodemap_object *)intern->ptr;
+       if (objmap->ht) {
+               if (objmap->nodetype == XML_ENTITY_NODE) {
+                       itemnode = (xmlNodePtr)xmlHashLookup(objmap->ht, named);
+               } else {
+                       notep = (xmlNotation *)xmlHashLookup(objmap->ht, named);
+                       itemnode = create_notation(notep->name, notep->PublicID, notep->SystemID);
+               }
+       } else {
+               nodep = dom_object_get_node(objmap->baseobj);
+               if (nodep) {
+                       itemnode = (xmlNodePtr)xmlHasNsProp(nodep, named, uri);
+               }
+       }
+
+       if (itemnode) {
+               DOM_RET_OBJ(rv, itemnode, &ret, objmap->baseobj);
+       } else {
+               RETVAL_NULL();
+       }
 }
 /* }}} end dom_namednodemap_get_named_item_ns */
 
index fc146051d5bd23e26d1dbb5f236d49a77e6657b6..e638ec003f4c0b9b72769d76dce16a17ec736555 100644 (file)
@@ -27,7 +27,6 @@
 #if HAVE_LIBXML && HAVE_DOM
 #include "php_dom.h"
 
-
 /*
 * class domnode 
 *
@@ -280,31 +279,13 @@ Since:
 */
 int dom_node_child_nodes_read(dom_object *obj, zval **retval TSRMLS_DC)
 {
-       xmlNodePtr nodep, last;
-       int ret;
-
-       nodep = dom_object_get_node(obj);
+       dom_object *intern;
 
-       if (dom_node_children_valid(nodep) == SUCCESS) {
-               if ((nodep->type == XML_DOCUMENT_NODE) || (nodep->type == XML_HTML_DOCUMENT_NODE)) {
-                       last = ((xmlDoc *) nodep)->children;
-               } else {
-                       last = nodep->children;
-               }
-       } else {
-               last = NULL;
-       }
+       ALLOC_ZVAL(*retval);
+       php_dom_create_interator(*retval, DOM_NODELIST TSRMLS_CC);
 
-       MAKE_STD_ZVAL(*retval);
-       array_init(*retval);
-       
-       while (last) {
-               zval *child;
-               MAKE_STD_ZVAL(child);
-               child = php_dom_create_object(last, &ret, NULL, child, obj TSRMLS_CC);
-               add_next_index_zval(*retval, child);
-               last = last->next;
-       }
+       intern = (dom_object *)zend_objects_get_address(*retval TSRMLS_CC);
+       dom_namednode_iter(obj, XML_ELEMENT_NODE, intern, NULL, NULL, NULL);
 
        return SUCCESS;
 }
@@ -446,28 +427,13 @@ Since:
 */
 int dom_node_attributes_read(dom_object *obj, zval **retval TSRMLS_DC)
 {
-       xmlNodePtr nodep;
-       xmlAttr *attr;
-       int ret;
-
-       nodep = dom_object_get_node(obj);
+       dom_object *intern;
 
        ALLOC_ZVAL(*retval);
+       php_dom_create_interator(*retval, DOM_NAMEDNODEMAP TSRMLS_CC);
 
-       if (nodep->type == XML_ELEMENT_NODE) {
-               attr = nodep->properties;
-               array_init(*retval);
-       
-               while (attr) {
-                       zval *curattr;
-                       MAKE_STD_ZVAL(curattr);
-                       curattr = php_dom_create_object((xmlNodePtr) attr, &ret, NULL, curattr, obj TSRMLS_CC);
-                       add_assoc_zval(*retval, (char *) attr->name, curattr);
-                       attr = attr->next;
-               }
-        } else {
-               ZVAL_NULL(*retval);
-        }
+       intern = (dom_object *)zend_objects_get_address(*retval TSRMLS_CC);
+       dom_namednode_iter(obj, XML_ATTRIBUTE_NODE, intern, NULL, NULL, NULL);
 
        return SUCCESS;
 }
index bcaee1f93e4c0861aaccc33c43e347973d58facc..5ecd2d763e7e801ae925c72ce2db297b3522e3a4 100644 (file)
@@ -49,23 +49,98 @@ Since:
 */
 int dom_nodelist_length_read(dom_object *obj, zval **retval TSRMLS_DC)
 {
-       ALLOC_ZVAL(*retval);
-       ZVAL_STRING(*retval, "TEST", 1);
+       dom_nnodemap_object *objmap;
+       xmlNodePtr nodep, curnode;
+       int count = 0;
+
+       objmap = (dom_nnodemap_object *)obj->ptr;
+       if (objmap->ht) {
+               count = xmlHashSize(objmap->ht);
+       } else {
+               nodep = dom_object_get_node(objmap->baseobj);
+               if (nodep) {
+                       if (objmap->nodetype == XML_ATTRIBUTE_NODE || objmap->nodetype == XML_ELEMENT_NODE) {
+                               curnode = nodep->children;
+                               if (curnode) {
+                                       count++;
+                                       while (curnode->next != NULL) {
+                                               count++;
+                                               curnode = curnode->next;
+                                       }
+                               }
+                       } else {
+                               if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
+                                       nodep = xmlDocGetRootElement((xmlDoc *) nodep);
+                               }
+                               curnode = dom_get_elements_by_tag_name_ns_raw(nodep, objmap->ns, objmap->local, &count, -1);
+                       }
+               }
+       }
+
+       MAKE_STD_ZVAL(*retval);
+       ZVAL_LONG(*retval, count);
        return SUCCESS;
 }
 
 /* }}} */
 
 
-
-
 /* {{{ proto domnode dom_nodelist_item(unsigned long index);
 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-844377136
 Since: 
 */
 PHP_FUNCTION(dom_nodelist_item)
 {
- DOM_NOT_IMPLEMENTED();
+       zval *id, *rv = NULL;
+       int index, ret;
+       dom_object *intern;
+       xmlNodePtr itemnode = NULL;
+
+       dom_nnodemap_object *objmap;
+       xmlNodePtr nodep, curnode;
+       int count = 0;
+
+       id = getThis();
+       
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &index) == FAILURE) {
+               return;
+       }
+
+       if (index >= 0) {
+               intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
+
+               objmap = (dom_nnodemap_object *)intern->ptr;
+               if (objmap->ht) {
+                       if (objmap->nodetype == XML_ENTITY_NODE) {
+                               itemnode = php_dom_libxml_hash_iter(objmap->ht, index);
+                       } else {
+                               itemnode = php_dom_libxml_notation_iter(objmap->ht, index);
+                       }
+               } else {
+                       nodep = dom_object_get_node(objmap->baseobj);
+                       if (nodep) {
+                               if (objmap->nodetype == XML_ATTRIBUTE_NODE || objmap->nodetype == XML_ELEMENT_NODE) {
+                                       curnode = nodep->children;
+                                       while (count < index && curnode != NULL) {
+                                               count++;
+                                               curnode = curnode->next;
+                                       }
+                                       itemnode = curnode;
+                               } else {
+                                       if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
+                                               nodep = xmlDocGetRootElement((xmlDoc *) nodep);
+                                       }
+                                       itemnode = dom_get_elements_by_tag_name_ns_raw(nodep, objmap->ns, objmap->local, &count, index);
+                               }
+                       }
+               }
+       }
+
+       if (itemnode) {
+               DOM_RET_OBJ(rv, itemnode, &ret, objmap->baseobj);
+       } else {
+               RETVAL_NULL();
+       }
 }
 /* }}} end dom_nodelist_item */
 #endif
index 592ff5736a8a7110e823bbf71e6456480b6f32bc..9ddf5ebfc0c980a93218b993a10f6c952420f4a3 100644 (file)
@@ -432,14 +432,20 @@ PHP_MINIT_FUNCTION(dom)
        zend_hash_merge(&dom_document_prop_handlers, &dom_node_prop_handlers, NULL, NULL, sizeof(dom_prop_handler), 0);
        zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_document_prop_handlers, sizeof(dom_document_prop_handlers), NULL);
 
-       REGISTER_DOM_CLASS(ce, "domnodelist", NULL, php_dom_nodelist_class_functions, dom_nodelist_class_entry);
-       
+       INIT_CLASS_ENTRY(ce, "domnodelist", php_dom_nodelist_class_functions);
+       ce.create_object = dom_nnodemap_objects_new;
+       dom_nodelist_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC);
+       dom_nodelist_class_entry->get_iterator = php_dom_get_iterator;
+
        zend_hash_init(&dom_nodelist_prop_handlers, 0, NULL, NULL, 1);
        dom_register_prop_handler(&dom_nodelist_prop_handlers, "length", dom_nodelist_length_read, NULL TSRMLS_CC);
        zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_nodelist_prop_handlers, sizeof(dom_nodelist_prop_handlers), NULL);
 
-       REGISTER_DOM_CLASS(ce, "domnamednodemap", NULL, php_dom_namednodemap_class_functions, dom_namednodemap_class_entry);
-       
+       INIT_CLASS_ENTRY(ce, "domnamednodemap", php_dom_namednodemap_class_functions);
+       ce.create_object = dom_nnodemap_objects_new;
+       dom_namednodemap_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC);
+       dom_namednodemap_class_entry->get_iterator = php_dom_get_iterator;
+
        zend_hash_init(&dom_namednodemap_prop_handlers, 0, NULL, NULL, 1);
        dom_register_prop_handler(&dom_namednodemap_prop_handlers, "length", dom_namednodemap_length_read, NULL TSRMLS_CC);
        zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_namednodemap_prop_handlers, sizeof(dom_namednodemap_prop_handlers), NULL);
@@ -686,7 +692,7 @@ PHP_MSHUTDOWN_FUNCTION(dom)
        uncomment the following line, this will tell you the amount of not freed memory
        and the total used memory into apaches error_log  */
 /*  xmlMemoryDump();*/
-
+xmlMemoryDump();
        return SUCCESS;
 }
 
@@ -773,7 +779,29 @@ void dom_objects_dtor(void *object, zend_object_handle handle TSRMLS_DC)
 }
 /* }}} */
 
-/* {{{ dom_objects_set_class */
+void dom_namednode_iter(dom_object *basenode, int ntype, dom_object *intern, xmlHashTablePtr ht, xmlChar *local, xmlChar *ns)
+{
+       dom_nnodemap_object *mapptr;
+       zval *baseobj = NULL;
+
+       mapptr = (dom_nnodemap_object *)intern->ptr;
+       if (basenode) {
+               MAKE_STD_ZVAL(baseobj);
+               baseobj->type = IS_OBJECT;
+               baseobj->is_ref = 1;
+               baseobj->value.obj.handle = basenode->handle;
+               baseobj->value.obj.handlers = &dom_object_handlers;
+               zval_copy_ctor(baseobj);
+       }
+       mapptr->baseobjptr = baseobj;
+       mapptr->baseobj = basenode;
+       mapptr->nodetype = ntype;
+       mapptr->ht = ht;
+       mapptr->local = local;
+       mapptr->ns = ns;
+
+}
+
 static dom_object* dom_objects_set_class(zend_class_entry *class_type TSRMLS_DC)
 {
        zend_class_entry *base_class;
@@ -801,7 +829,6 @@ static dom_object* dom_objects_set_class(zend_class_entry *class_type TSRMLS_DC)
 
        return intern;
 }
-/* }}} */
 
 /* {{{ dom_objects_new */
 zend_object_value dom_objects_new(zend_class_entry *class_type TSRMLS_DC)
@@ -837,6 +864,70 @@ zend_object_value dom_xpath_objects_new(zend_class_entry *class_type TSRMLS_DC)
 /* }}} */
 #endif
 
+void dom_nnodemap_objects_dtor(void *object, zend_object_handle handle TSRMLS_DC)
+{
+       dom_nnodemap_object *objmap;
+       zval *baseobj;
+       dom_object *intern = (dom_object *)object;
+
+       php_libxml_decrement_doc_ref((php_libxml_node_object *)intern TSRMLS_CC);
+       objmap = (dom_nnodemap_object *)intern->ptr;
+       if (objmap) {
+               if (objmap->local) {
+                       xmlFree(objmap->local);
+               }
+               if (objmap->ns) {
+                       xmlFree(objmap->ns);
+               }
+               if (objmap->baseobjptr) {
+                       baseobj = objmap->baseobjptr;
+                       zval_ptr_dtor((zval **)&baseobj);
+               }
+               efree(objmap);
+       }
+
+       zend_hash_destroy(intern->std.properties);
+       FREE_HASHTABLE(intern->std.properties);
+
+       efree(object);
+}
+
+zend_object_value dom_nnodemap_objects_new(zend_class_entry *class_type TSRMLS_DC)
+{
+       zend_object_value retval;
+       dom_object *intern;
+       dom_nnodemap_object *objmap;
+       
+       intern = dom_objects_set_class(class_type TSRMLS_CC);
+       intern->ptr = emalloc(sizeof(dom_nnodemap_object));
+       objmap = (dom_nnodemap_object *)intern->ptr;
+       objmap->baseobj = NULL;
+       objmap->baseobjptr = NULL;
+       objmap->nodetype = 0;
+       objmap->ht = NULL;
+       objmap->local = NULL;
+       objmap->ns = NULL;
+
+       retval.handle = zend_objects_store_put(intern, dom_nnodemap_objects_dtor, dom_objects_clone TSRMLS_CC);
+       intern->handle = retval.handle;
+       retval.handlers = &dom_object_handlers;
+
+       return retval;
+}
+
+void php_dom_create_interator(zval *return_value, int ce_type TSRMLS_DC)
+{
+       zend_class_entry *ce;
+
+       if (ce_type == DOM_NAMEDNODEMAP) {
+               ce = dom_namednodemap_class_entry;
+       } else {
+               ce = dom_nodelist_class_entry;
+       }
+
+       object_init_ex(return_value, ce);
+}
+
 /* {{{ php_dom_create_object */
 zval *php_dom_create_object(xmlNodePtr obj, int *found, zval *wrapper_in, zval *return_value, dom_object *domobj TSRMLS_DC)
 {
@@ -995,24 +1086,27 @@ int dom_has_feature(char *feature, char *version)
 }
 /* }}} end dom_has_feature */
 
-/* {{{ void dom_element_get_elements_by_tag_name_ns_raw(xmlNodePtr nodep, char *ns, char *local, zval **retval  TSRMLS_DC) */
-void dom_get_elements_by_tag_name_ns_raw(xmlNodePtr nodep, char *ns, char *local, zval **retval, dom_object *intern  TSRMLS_DC)
+xmlNode *dom_get_elements_by_tag_name_ns_raw(xmlNodePtr nodep, char *ns, char *local, int *cur, int index)
 {
-       int ret;
+       xmlNodePtr ret = NULL;
 
-       while (nodep != NULL) {
+       while (nodep != NULL && (*cur <= index || index == -1)) {
                if (nodep->type == XML_ELEMENT_NODE && xmlStrEqual(nodep->name, local)) {
                        if (ns == NULL || (nodep->ns != NULL && xmlStrEqual(nodep->ns->href, ns))) {
-                               zval *child;
-                               MAKE_STD_ZVAL(child);
-
-                               child = php_dom_create_object(nodep, &ret, NULL, child, intern TSRMLS_CC);
-                               add_next_index_zval(*retval, child);
+                               if (*cur == index) {
+                                       ret = nodep;
+                                       break;
+                               }
+                               (*cur)++;
                        }
                }
-               dom_get_elements_by_tag_name_ns_raw(nodep->children, ns, local, retval, intern TSRMLS_CC);
+               ret = dom_get_elements_by_tag_name_ns_raw(nodep->children, ns, local, cur, index);
+               if (ret != NULL) {
+                       break;
+               }
                nodep = nodep->next;
        }
+       return ret;
 }
 /* }}} end dom_element_get_elements_by_tag_name_ns_raw */
 
index 6c400d17548a4849b7b84a9b281dcae831564955..ea99413d2027d5d19e7a568e0b978e781cce5c5f 100644 (file)
@@ -61,13 +61,28 @@ extern zend_module_entry dom_module_entry;
     therefore it's easier for the script-programmers to check, what's working how
    Can be checked with phpversion("dom");
 */
-#define DOM_API_VERSION "20030901"
+#define DOM_API_VERSION "20031129"
+
+typedef struct _dom_nnodemap_object {
+       dom_object *baseobj;
+       int nodetype;
+       xmlHashTable *ht;
+       xmlChar *local;
+       xmlChar *ns;
+       zval *baseobjptr;
+} dom_nnodemap_object;
+
+typedef struct {
+       zend_object_iterator     intern;
+       zval *curobj;
+} php_dom_iterator;
 
 #include "dom_fe.h"
 
 dom_object *dom_object_get_data(xmlNodePtr obj);
 dom_doc_propsptr dom_get_doc_props(php_libxml_ref_obj *document);
 zend_object_value dom_objects_new(zend_class_entry *class_type TSRMLS_DC);
+zend_object_value dom_nnodemap_objects_new(zend_class_entry *class_type TSRMLS_DC);
 #if defined(LIBXML_XPATH_ENABLED)
 zend_object_value dom_xpath_objects_new(zend_class_entry *class_type TSRMLS_DC);
 #endif
@@ -79,12 +94,18 @@ xmlNsPtr dom_get_ns(xmlNodePtr node, char *uri, int *errorcode, char *prefix);
 void dom_set_old_ns(xmlDoc *doc, xmlNs *ns);
 xmlNsPtr dom_get_nsdecl(xmlNode *node, xmlChar *localName);
 void dom_normalize (xmlNodePtr nodep TSRMLS_DC);
-void dom_get_elements_by_tag_name_ns_raw(xmlNodePtr nodep, char *ns, char *local, zval **retval, dom_object *intern  TSRMLS_DC);
+xmlNode *dom_get_elements_by_tag_name_ns_raw(xmlNodePtr nodep, char *ns, char *local, int *cur, int index);
 void php_dom_create_implementation(zval **retval  TSRMLS_DC);
 int dom_hierarchy(xmlNodePtr parent, xmlNodePtr child);
 int dom_has_feature(char *feature, char *version);
 int dom_node_is_read_only(xmlNodePtr node);
 int dom_node_children_valid(xmlNodePtr node);
+void php_dom_create_interator(zval *return_value, int ce_type TSRMLS_DC);
+void dom_namednode_iter(dom_object *basenode, int ntype, dom_object *intern, xmlHashTablePtr ht, xmlChar *local, xmlChar *ns);
+xmlNodePtr create_notation(const xmlChar *name, const xmlChar *ExternalID, const xmlChar *SystemID);
+xmlNode *php_dom_libxml_hash_iter(xmlHashTable *ht, int index);
+xmlNode *php_dom_libxml_notation_iter(xmlHashTable *ht, int index);
+zend_object_iterator *php_dom_get_iterator(zend_class_entry *ce, zval *object TSRMLS_DC);
 
 #define REGISTER_DOM_CLASS(ce, name, parent_ce, funcs, entry) \
 INIT_CLASS_ENTRY(ce, name, funcs); \
@@ -109,6 +130,9 @@ entry = zend_register_internal_class_ex(&ce, parent_ce, NULL TSRMLS_CC);
        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not yet implemented"); \
        return;
 
+#define DOM_NODELIST 0
+#define DOM_NAMEDNODEMAP 1
+
 PHP_MINIT_FUNCTION(dom);
 PHP_MSHUTDOWN_FUNCTION(dom);
 PHP_MINFO_FUNCTION(dom);
index cf3298db6d35e9b4ab5b44b2fb7c51993672119e..a0c78fbb0a19f839d92cedf22f92af8a4c049e60 100644 (file)
@@ -65,7 +65,7 @@ $attrs = $rootnode->attributes;
 print_node_list($attrs);
 
 echo "--------- children of an attribute\n";
-$children = current($attrs)->childNodes;
+$children = $attrs->item(0)->childNodes;
 print_node_list($children);
 
 echo "--------- Add child to root\n";
@@ -85,8 +85,8 @@ $children = $rootnode->getElementsByTagName("Silly");
 print_node_list($children);
 
 echo "--------- Unlink Node\n";
-print_node($children[0]);
-$rootnode->removeChild($children[0]);
+print_node($children->item(0));
+$rootnode->removeChild($children->item(0));
 print_node_list($rootnode->childNodes);
 print $dom->savexml();
 
index 96acddc6691cc247a34554017112c6bf76f0259c..792d6f2dbc4818b45a6e5d33964d0487de5d5af7 100644 (file)
@@ -24,7 +24,7 @@ function print_node($node)
 {
   print "Node Name: " . $node->nodeName;
   print "\nNode Type: " . $node->nodeType;
-  $child_count = count($node->childNodes);
+  $child_count = $node->childNodes->length;
   print "\nNum Children: " . $child_count;
   if($child_count <= 1){
     print "\nNode Content: " . $node->nodeValue;
index 8515eecbfbef93d8e3c27bd2315323b310cca820..86f492e2b8407c1c49a0fe22c22250f1231f4244 100644 (file)
@@ -24,9 +24,6 @@
 
 #include "ext/libxml/php_libxml.h"
 
-zend_class_entry *dom_node_class_entry;
-
-
 typedef struct _dom_doc_props {
        int formatoutput;
        int validateonparse;
@@ -59,6 +56,7 @@ typedef struct _dom_object {
 
 #define PHP_DOM_EXPORT(__type) PHPAPI __type
 
+PHP_DOM_EXPORT(zend_class_entry *) dom_node_class_entry;
 PHP_DOM_EXPORT(dom_object *) php_dom_object_get_data(xmlNodePtr obj);
 PHP_DOM_EXPORT(zval *) php_dom_create_object(xmlNodePtr obj, int *found, zval *in, zval* return_value, dom_object *domobj TSRMLS_DC);
 PHP_DOM_EXPORT(xmlNodePtr) dom_object_get_node(dom_object *obj);