diff options
author | Rob Richards <rrichards@php.net> | 2004-01-10 11:50:25 +0000 |
---|---|---|
committer | Rob Richards <rrichards@php.net> | 2004-01-10 11:50:25 +0000 |
commit | 394bf2ba5b457a5befed5a7fbadae0ce50e024d4 (patch) | |
tree | 478abdaee2e072445bf18504a0f4e34bbf1cd2fe | |
parent | a72c1ab93be75e9e206e6ba90fe04c2676110e72 (diff) | |
download | php-git-394bf2ba5b457a5befed5a7fbadae0ce50e024d4.tar.gz |
XPath query returns nodelist object rather than array
-rw-r--r-- | ext/dom/dom_iterators.c | 60 | ||||
-rw-r--r-- | ext/dom/nodelist.c | 73 | ||||
-rw-r--r-- | ext/dom/php_dom.h | 2 | ||||
-rw-r--r-- | ext/dom/xpath.c | 24 |
4 files changed, 107 insertions, 52 deletions
diff --git a/ext/dom/dom_iterators.c b/ext/dom/dom_iterators.c index 2dc903c5e4..f71bc60e0e 100644 --- a/ext/dom/dom_iterators.c +++ b/ext/dom/dom_iterators.c @@ -188,6 +188,8 @@ static void php_dom_iterator_move_forward(zend_object_iterator *iter TSRMLS_DC) dom_object *nnmap; dom_nnodemap_object *objmap; int ret, previndex=1; + HashTable *nodeht; + pval **entry; php_dom_iterator *iterator = (php_dom_iterator *)iter; @@ -199,18 +201,26 @@ static void php_dom_iterator_move_forward(zend_object_iterator *iter TSRMLS_DC) intern = (dom_object *)zend_object_store_get_object(curobj TSRMLS_CC); if (intern != NULL && intern->ptr != NULL) { if (objmap->ht == NULL) { - curnode = (xmlNodePtr)((php_libxml_node_ptr *)intern->ptr)->node; - if (objmap->nodetype == XML_ATTRIBUTE_NODE || objmap->nodetype == XML_ELEMENT_NODE) { - curnode = curnode->next; + if (objmap->nodetype == DOM_NODESET) { + nodeht = HASH_OF(objmap->baseobjptr); + zend_hash_move_forward(nodeht); + if (zend_hash_get_current_data(nodeht, (void **) &entry)==SUCCESS) { + curattr = *entry; + } } else { - /* Nav the tree evey time as this is LIVE */ - basenode = dom_object_get_node(objmap->baseobj); - if (basenode && (basenode->type == XML_DOCUMENT_NODE || basenode->type == XML_HTML_DOCUMENT_NODE)) { - basenode = xmlDocGetRootElement((xmlDoc *) basenode); + curnode = (xmlNodePtr)((php_libxml_node_ptr *)intern->ptr)->node; + if (objmap->nodetype == XML_ATTRIBUTE_NODE || objmap->nodetype == XML_ELEMENT_NODE) { + curnode = curnode->next; } else { - basenode = basenode->children; + /* Nav the tree evey time as this is LIVE */ + basenode = dom_object_get_node(objmap->baseobj); + if (basenode && (basenode->type == XML_DOCUMENT_NODE || basenode->type == XML_HTML_DOCUMENT_NODE)) { + basenode = xmlDocGetRootElement((xmlDoc *) basenode); + } else { + basenode = basenode->children; + } + curnode = dom_get_elements_by_tag_name_ns_raw(basenode, objmap->ns, objmap->local, &previndex, iter->index); } - curnode = dom_get_elements_by_tag_name_ns_raw(basenode, objmap->ns, objmap->local, &previndex, iter->index); } } else { if (objmap->nodetype == XML_ENTITY_NODE) { @@ -243,9 +253,11 @@ zend_object_iterator *php_dom_get_iterator(zend_class_entry *ce, zval *object TS { dom_object *intern; dom_nnodemap_object *objmap; - xmlNodePtr nodep, curnode; + xmlNodePtr nodep, curnode=NULL; zval *curattr = NULL; int ret, curindex = 0; + HashTable *nodeht; + pval **entry; php_dom_iterator *iterator = emalloc(sizeof(php_dom_iterator)); @@ -256,20 +268,28 @@ zend_object_iterator *php_dom_get_iterator(zend_class_entry *ce, zval *object TS intern = (dom_object *)zend_object_store_get_object(object TSRMLS_CC); objmap = (dom_nnodemap_object *)intern->ptr; if (objmap->ht == NULL) { - nodep = (xmlNode *)dom_object_get_node(objmap->baseobj); - if (objmap->nodetype == XML_ATTRIBUTE_NODE || objmap->nodetype == XML_ELEMENT_NODE) { - if (objmap->nodetype == XML_ATTRIBUTE_NODE) { - curnode = (xmlNodePtr) nodep->properties; - } else { - curnode = (xmlNodePtr) nodep->children; + if (objmap->nodetype == DOM_NODESET) { + nodeht = HASH_OF(objmap->baseobjptr); + zend_hash_internal_pointer_reset(nodeht); + if (zend_hash_get_current_data(nodeht, (void **) &entry)==SUCCESS) { + curattr = *entry; } } else { - if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) { - nodep = xmlDocGetRootElement((xmlDoc *) nodep); + nodep = (xmlNode *)dom_object_get_node(objmap->baseobj); + if (objmap->nodetype == XML_ATTRIBUTE_NODE || objmap->nodetype == XML_ELEMENT_NODE) { + if (objmap->nodetype == XML_ATTRIBUTE_NODE) { + curnode = (xmlNodePtr) nodep->properties; + } else { + curnode = (xmlNodePtr) nodep->children; + } } else { - nodep = nodep->children; + if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) { + nodep = xmlDocGetRootElement((xmlDoc *) nodep); + } else { + nodep = nodep->children; + } + curnode = dom_get_elements_by_tag_name_ns_raw(nodep, objmap->ns, objmap->local, &curindex, 0); } - curnode = dom_get_elements_by_tag_name_ns_raw(nodep, objmap->ns, objmap->local, &curindex, 0); } } else { curnode = php_dom_libxml_hash_iter(objmap->ht, 0); diff --git a/ext/dom/nodelist.c b/ext/dom/nodelist.c index 9c56e48844..a15228b376 100644 --- a/ext/dom/nodelist.c +++ b/ext/dom/nodelist.c @@ -52,29 +52,35 @@ int dom_nodelist_length_read(dom_object *obj, zval **retval TSRMLS_DC) dom_nnodemap_object *objmap; xmlNodePtr nodep, curnode; int count = 0; + HashTable *nodeht; 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) { + if (objmap->nodetype == DOM_NODESET) { + nodeht = HASH_OF(objmap->baseobjptr); + count = zend_hash_num_elements(nodeht); + } 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++; - curnode = curnode->next; + 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); } else { - nodep = nodep->children; + if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) { + nodep = xmlDocGetRootElement((xmlDoc *) nodep); + } else { + nodep = nodep->children; + } + curnode = dom_get_elements_by_tag_name_ns_raw(nodep, objmap->ns, objmap->local, &count, -1); } - curnode = dom_get_elements_by_tag_name_ns_raw(nodep, objmap->ns, objmap->local, &count, -1); } } } @@ -101,6 +107,8 @@ PHP_FUNCTION(dom_nodelist_item) dom_nnodemap_object *objmap; xmlNodePtr nodep, curnode; int count = 0; + HashTable *nodeht; + pval **entry; id = getThis(); @@ -119,22 +127,31 @@ PHP_FUNCTION(dom_nodelist_item) 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); + if (objmap->nodetype == DOM_NODESET) { + nodeht = HASH_OF(objmap->baseobjptr); + if (zend_hash_index_find(nodeht, index, (void **) &entry)==SUCCESS) { + *return_value = **entry; + zval_copy_ctor(return_value); + return; + } + } 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 { - nodep = nodep->children; + if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) { + nodep = xmlDocGetRootElement((xmlDoc *) nodep); + } else { + nodep = nodep->children; + } + itemnode = dom_get_elements_by_tag_name_ns_raw(nodep, objmap->ns, objmap->local, &count, index); } - itemnode = dom_get_elements_by_tag_name_ns_raw(nodep, objmap->ns, objmap->local, &count, index); } } } diff --git a/ext/dom/php_dom.h b/ext/dom/php_dom.h index ad36cf23d6..d5e976e953 100644 --- a/ext/dom/php_dom.h +++ b/ext/dom/php_dom.h @@ -62,6 +62,8 @@ extern zend_module_entry dom_module_entry; Can be checked with phpversion("dom"); */ #define DOM_API_VERSION "20031129" +/* Define a custom type for iterating using an unused nodetype */ +#define DOM_NODESET XML_XINCLUDE_START typedef struct _dom_nnodemap_object { dom_object *baseobj; diff --git a/ext/dom/xpath.c b/ext/dom/xpath.c index fd0f72dc3a..2961ff4a09 100644 --- a/ext/dom/xpath.c +++ b/ext/dom/xpath.c @@ -128,10 +128,20 @@ PHP_FUNCTION(dom_xpath_register_ns) RETURN_TRUE; } +static void dom_xpath_iter(zval *baseobj, dom_object *intern) +{ + dom_nnodemap_object *mapptr; + + mapptr = (dom_nnodemap_object *)intern->ptr; + mapptr->baseobjptr = baseobj; + mapptr->nodetype = DOM_NODESET; + +} + /* {{{ proto domnodelist dom_xpath_query(string expr [,domNode context]); */ PHP_FUNCTION(dom_xpath_query) { - zval *id, *context = NULL; + zval *id, *retval, *context = NULL; xmlXPathContextPtr ctxp; xmlNodePtr nodep = NULL; xmlXPathObjectPtr xpathobjp; @@ -200,6 +210,10 @@ PHP_FUNCTION(dom_xpath_query) if (! xpathobjp) { RETURN_FALSE; } + + MAKE_STD_ZVAL(retval); + array_init(retval); + if (xpathobjp->type == XPATH_NODESET) { int i; xmlNodeSetPtr nodesetp; @@ -209,8 +223,6 @@ PHP_FUNCTION(dom_xpath_query) RETURN_FALSE; } - array_init(return_value); - for (i = 0; i < nodesetp->nodeNr; i++) { xmlNodePtr node = nodesetp->nodeTab[i]; zval *child; @@ -236,10 +248,14 @@ PHP_FUNCTION(dom_xpath_query) node->ns = curns; } child = php_dom_create_object(node, &ret, NULL, child, intern TSRMLS_CC); - add_next_index_zval(return_value, child); + add_next_index_zval(retval, child); } } + php_dom_create_interator(return_value, DOM_NODELIST TSRMLS_CC); + intern = (dom_object *)zend_objects_get_address(return_value TSRMLS_CC); + dom_xpath_iter(retval, intern); + xmlXPathFreeObject(xpathobjp); } /* }}} end dom_xpath_query */ |