summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Richards <rrichards@php.net>2003-11-29 20:40:18 +0000
committerRob Richards <rrichards@php.net>2003-11-29 20:40:18 +0000
commit6ac34646acf2f7088614c6c778b17e839e1bf161 (patch)
treed91c6fd9a959fa366f9d798e0cceb1ab42d957b4
parent154db581aead2c17314d300c076d57d917d93b9e (diff)
downloadphp-git-6ac34646acf2f7088614c6c778b17e839e1bf161.tar.gz
implement namednodemap and nodelist
fix xsl/dom integration under windows update tests and examples
-rw-r--r--ext/dom/config.m42
-rw-r--r--ext/dom/document.c25
-rw-r--r--ext/dom/documenttype.c115
-rw-r--r--ext/dom/element.c22
-rw-r--r--ext/dom/examples/dom1.inc2
-rw-r--r--ext/dom/examples/dom1.php6
-rw-r--r--ext/dom/namednodemap.c149
-rw-r--r--ext/dom/node.c52
-rw-r--r--ext/dom/nodelist.c85
-rw-r--r--ext/dom/php_dom.c128
-rw-r--r--ext/dom/php_dom.h28
-rw-r--r--ext/dom/tests/dom001.phpt6
-rw-r--r--ext/dom/tests/dom_test.inc2
-rw-r--r--ext/dom/xml_common.h4
14 files changed, 418 insertions, 208 deletions
diff --git a/ext/dom/config.m4 b/ext/dom/config.m4
index 41699b0807..82c97e6bd3 100644
--- a/ext/dom/config.m4
+++ b/ext/dom/config.m4
@@ -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)
diff --git a/ext/dom/document.c b/ext/dom/document.c
index 8246d891f7..034b83f399 100644
--- a/ext/dom/document.c
+++ b/ext/dom/document.c
@@ -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 */
diff --git a/ext/dom/documenttype.c b/ext/dom/documenttype.c
index cd6af0d076..036e825a6d 100644
--- a/ext/dom/documenttype.c
+++ b/ext/dom/documenttype.c
@@ -27,57 +27,6 @@
#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;
}
diff --git a/ext/dom/element.c b/ext/dom/element.c
index 84b01618bd..bd146637e6 100644
--- a/ext/dom/element.c
+++ b/ext/dom/element.c
@@ -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 */
diff --git a/ext/dom/examples/dom1.inc b/ext/dom/examples/dom1.inc
index 96acddc669..792d6f2dbc 100644
--- a/ext/dom/examples/dom1.inc
+++ b/ext/dom/examples/dom1.inc
@@ -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;
diff --git a/ext/dom/examples/dom1.php b/ext/dom/examples/dom1.php
index 8654b19c2f..99125a2a37 100644
--- a/ext/dom/examples/dom1.php
+++ b/ext/dom/examples/dom1.php
@@ -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();
diff --git a/ext/dom/namednodemap.c b/ext/dom/namednodemap.c
index ada109ad80..1e4eefbe23 100644
--- a/ext/dom/namednodemap.c
+++ b/ext/dom/namednodemap.c
@@ -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 */
diff --git a/ext/dom/node.c b/ext/dom/node.c
index fc146051d5..e638ec003f 100644
--- a/ext/dom/node.c
+++ b/ext/dom/node.c
@@ -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;
}
diff --git a/ext/dom/nodelist.c b/ext/dom/nodelist.c
index bcaee1f93e..5ecd2d763e 100644
--- a/ext/dom/nodelist.c
+++ b/ext/dom/nodelist.c
@@ -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
diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c
index 592ff5736a..9ddf5ebfc0 100644
--- a/ext/dom/php_dom.c
+++ b/ext/dom/php_dom.c
@@ -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 */
diff --git a/ext/dom/php_dom.h b/ext/dom/php_dom.h
index 6c400d1754..ea99413d20 100644
--- a/ext/dom/php_dom.h
+++ b/ext/dom/php_dom.h
@@ -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);
diff --git a/ext/dom/tests/dom001.phpt b/ext/dom/tests/dom001.phpt
index cf3298db6d..a0c78fbb0a 100644
--- a/ext/dom/tests/dom001.phpt
+++ b/ext/dom/tests/dom001.phpt
@@ -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();
diff --git a/ext/dom/tests/dom_test.inc b/ext/dom/tests/dom_test.inc
index 96acddc669..792d6f2dbc 100644
--- a/ext/dom/tests/dom_test.inc
+++ b/ext/dom/tests/dom_test.inc
@@ -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;
diff --git a/ext/dom/xml_common.h b/ext/dom/xml_common.h
index 8515eecbfb..86f492e2b8 100644
--- a/ext/dom/xml_common.h
+++ b/ext/dom/xml_common.h
@@ -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);