]> granicus.if.org Git - php/commitdiff
Major bugfix for consistency.
authorMarcus Boerger <helly@php.net>
Sat, 17 Jan 2004 19:41:32 +0000 (19:41 +0000)
committerMarcus Boerger <helly@php.net>
Sat, 17 Jan 2004 19:41:32 +0000 (19:41 +0000)
# After long discussions we came to a conclusion on how to make this
# extension consistent in itself.
# Thanks to Rob for all the work

18 files changed:
ext/simplexml/CREDITS
ext/simplexml/README
ext/simplexml/php_simplexml.h
ext/simplexml/simplexml.c
ext/simplexml/tests/006.phpt
ext/simplexml/tests/007.phpt
ext/simplexml/tests/008.phpt
ext/simplexml/tests/011.phpt
ext/simplexml/tests/012.phpt
ext/simplexml/tests/014.phpt
ext/simplexml/tests/014a.phpt
ext/simplexml/tests/014b.phpt
ext/simplexml/tests/015.phpt
ext/simplexml/tests/016.phpt
ext/simplexml/tests/017.phpt
ext/simplexml/tests/018.phpt
ext/simplexml/tests/019.phpt [new file with mode: 0755]
ext/simplexml/tests/bug25756.phpt [deleted file]

index 4a40338137d669d1063bb5abe84f361a74c1a6aa..eaa36f32458bd2e9a0ed95b3a53cd8b3c01bd236 100644 (file)
@@ -1,2 +1,2 @@
 simplexml
-Sterling Hughes, Marcus Boerger
+Sterling Hughes, Marcus Boerger, Rob Richards
index 9a867157f2b88ac566b0e9f9ad1b4d3ccef58eb8..f99f6ac3c9f8aef9e6cb9a4b6fefc952db9c12ab 100755 (executable)
@@ -2,18 +2,23 @@ SimpleXML is meant to be an easy way to access XML data.
 
 SimpleXML objects follow four basic rules:
 
-1) properties denote elements
+1) properties denote element iterators
 2) numeric indices denote elements
 3) non numeric indices denote attributes
 4) string conversion allows to access TEXT data
 
+When iterating proerties then the extension always iterates over
+all nodes with that elemtnt name. Thus method childen() must be 
+called to iterate over subnodes. But also doing the following:
+foreach $obj->node_name as $elem) {
+  // do something with $elem
+}
+Always result in iteration of 'node_name' elements. So no further 
+check is needed to distinguish the number of nodes of that type.
+
 When an elements TEXT data is being accessed through a property
 then the result does not include the TEXT data of subelements.
 
-If PHP is compiled with ext/SPL being compiled into the binary
-then SimpleXML objects implement the interface RecursiveIterator 
-so that they can be iterated recursively (http://pecl.php.net/spl).
-
 Known issues
 ============
 
index f4f5d744561655954214e1cc785b5d852d73196e..4b05cfa06ecc22c5a53fc0312da59a444de88133 100644 (file)
@@ -65,14 +65,20 @@ typedef struct {
        simplexml_nsmap *nsmapptr;
        xmlXPathContextPtr xpath;
        struct {
-               xmlNodePtr            node;
+               php_libxml_node_ptr   *node;
+               int                   itertype;
                char                  *name;
-               int                   namelen;
+               char                  *nsprefix;
+               int                   type;
                zval                  *data;
        } iter;
 } php_sxe_object;
 
-
+#define SXE_ITER_NONE 0
+#define SXE_ITER_ELEMENT 1
+#define SXE_ITER_ATTR 2
+#define SXE_ITER_CHILD 3
+#define SXE_ITER_ATTRLIST 4
 
 #ifdef ZTS
 #define SIMPLEXML_G(v) TSRMG(simplexml_globals_id, zend_simplexml_globals *, v)
index 41403e754c30f0569b21e995bdc7fb6d00a4209c..a2513bcf9c0bc0ede1decb6e5bef0fef9ae46a77 100644 (file)
@@ -14,6 +14,7 @@
   +----------------------------------------------------------------------+
   | Author: Sterling Hughes <sterling@php.net>                           |
   |         Marcus Boerger <helly@php.net>                               |
+  |         Rob Richards <rrichards@php.net>                             |
   +----------------------------------------------------------------------+
 */
 
@@ -58,7 +59,7 @@ php_sxe_fetch_object(zval *object TSRMLS_DC)
 
 /* {{{ _node_as_zval()
  */
-static void _node_as_zval(php_sxe_object *sxe, xmlNodePtr node, zval *value TSRMLS_DC)
+static void _node_as_zval(php_sxe_object *sxe, xmlNodePtr node, zval *value, int itertype, char *name, char *prefix TSRMLS_DC)
 {
        php_sxe_object *subnode;
 
@@ -67,6 +68,13 @@ static void _node_as_zval(php_sxe_object *sxe, xmlNodePtr node, zval *value TSRM
        subnode->document->refcount++;
        subnode->nsmapptr = sxe->nsmapptr;
        subnode->nsmapptr->refcount++;
+       subnode->iter.type = itertype;
+       if (name) {
+               subnode->iter.name = xmlStrdup(name);
+       }
+       if (prefix) {
+               subnode->iter.nsprefix = xmlStrdup(prefix);
+       }
 
        php_libxml_increment_node_ptr((php_libxml_node_object *)subnode, node, NULL TSRMLS_CC);
 
@@ -95,16 +103,40 @@ static void _node_as_zval(php_sxe_object *sxe, xmlNodePtr node, zval *value TSRM
        } \
 }
 
+static void php_sxe_reset_iterator(php_sxe_object *sxe TSRMLS_DC);
+
+static xmlNodePtr php_sxe_get_first_node(php_sxe_object *sxe, xmlNodePtr node TSRMLS_DC) {
+       php_sxe_object *intern;
+       xmlNodePtr retnode = NULL;
+
+       if (sxe && sxe->iter.type != SXE_ITER_NONE) {
+               php_sxe_reset_iterator(sxe TSRMLS_CC);
+               if (sxe->iter.data) {
+                       intern = (php_sxe_object *)zend_object_store_get_object(sxe->iter.data TSRMLS_CC);
+                       GET_NODE(intern, retnode)
+               }
+               return retnode;
+       } else {
+               return node;
+       }
+}
 
 /* {{{ match_ns()
  */
 static inline int 
 match_ns(php_sxe_object *sxe, xmlNodePtr node, xmlChar *name)
 {
-       xmlChar *prefix;
+       xmlChar *prefix = NULL;
        
-       if (sxe->nsmapptr) {
-               prefix = xmlHashLookup(sxe->nsmapptr->nsmap, node->ns->href);
+       if (name == NULL && (node->ns == NULL || node->ns->prefix == NULL)) {
+               return 1;
+       }
+
+       if (node->ns) {
+               if (sxe->nsmapptr) {
+                       prefix = xmlHashLookup(sxe->nsmapptr->nsmap, node->ns->href);
+               }
+               
                if (prefix == NULL) {
                        prefix = (xmlChar*)node->ns->prefix;
                }
@@ -116,7 +148,7 @@ match_ns(php_sxe_object *sxe, xmlNodePtr node, xmlChar *name)
                if (!xmlStrcmp(prefix, name)) {
                        return 1;
                }
-       }
+       }       
 
        return 0;
 }
@@ -127,20 +159,28 @@ match_ns(php_sxe_object *sxe, xmlNodePtr node, xmlChar *name)
 static zval * sxe_prop_dim_read(zval *object, zval *member, zend_bool elements, zend_bool attribs, zend_bool silent TSRMLS_DC)
 {
        zval           *return_value;
-       zval           *value = NULL;
        php_sxe_object *sxe;
        char           *name;
-       char           *contents;
        xmlNodePtr      node;
        xmlAttrPtr      attr;
-       int             counter = 0;
        zval            tmp_zv;
+       int                             nodendx = 0;
+       char                    *prefix;
 
-       if (Z_TYPE_P(member) != IS_STRING) {
-               tmp_zv = *member;
-               zval_copy_ctor(&tmp_zv);
-               member = &tmp_zv;
-               convert_to_string(member);
+       sxe = php_sxe_fetch_object(object TSRMLS_CC);
+
+       if (Z_TYPE_P(member) == IS_LONG) {
+               if (sxe->iter.type != SXE_ITER_ATTR) {
+                       attribs = 0;
+                       elements = 1;
+               }
+       } else {
+               if (Z_TYPE_P(member) != IS_STRING) {
+                       tmp_zv = *member;
+                       zval_copy_ctor(&tmp_zv);
+                       member = &tmp_zv;
+                       convert_to_string(member);
+               }
        }
 
        MAKE_STD_ZVAL(return_value);
@@ -148,86 +188,64 @@ static zval * sxe_prop_dim_read(zval *object, zval *member, zend_bool elements,
 
        name = Z_STRVAL_P(member);
 
-       sxe = php_sxe_fetch_object(object TSRMLS_CC);
-
        GET_NODE(sxe, node);
 
+       if (sxe->iter.type != SXE_ITER_CHILD) {
+               node = php_sxe_get_first_node(sxe, node TSRMLS_CC);
+       }
+
        if (node) {
                if (attribs) {
-                       xmlChar *localname, *prefix=NULL;
-                       localname = xmlSplitQName2(name, &prefix);
-                       if (localname == NULL) {
-                               localname = (xmlChar *)name;
-                       }
+                       
                        attr = node->properties;
                        while (attr) {
-                               if (!xmlStrcmp(attr->name, localname) && (prefix==NULL || 
-                                       (attr->ns && (!xmlStrcmp(attr->ns->prefix, prefix) || match_ns(sxe, (xmlNodePtr) attr, prefix))))) {
-
-                                       APPEND_PREV_ELEMENT(counter, value);
-                                       
-                                       MAKE_STD_ZVAL(value);
-                                       contents = xmlNodeListGetString((xmlDocPtr) sxe->document->ptr, attr->children, 1);
-                                       ZVAL_STRING(value, contents, 1);
-                                       if (contents) {
-                                               xmlFree(contents);
-                                       }
-                                       APPEND_CUR_ELEMENT(counter, value);
+                               if (!xmlStrcmp(attr->name, name) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix)) {
+                                       _node_as_zval(sxe, (xmlNodePtr) attr, return_value, SXE_ITER_NONE, NULL, NULL TSRMLS_CC);
+                                       break;
                                }
                                attr = attr->next;
                        }
-                       if (prefix) {
-                               xmlFree(prefix);
-                               if (localname) {
-                                       xmlFree(localname);
-                               }
-                       }
                }
 
                if (elements) {
                        if (!sxe->node) {
                                php_libxml_increment_node_ptr((php_libxml_node_object *)sxe, node, NULL TSRMLS_CC);
                        }
-                       node = node->children;
-       
-                       while (node) {
-                               SKIP_TEXT(node);
-                               
-                               do if (node->ns) {
-                                       if (node->parent->ns) {
-                                               if (!xmlStrcmp(node->ns->href, node->parent->ns->href)) {
+                       if (Z_TYPE_P(member) == IS_LONG) {
+                               if (sxe->iter.type == SXE_ITER_NONE || sxe->iter.type == SXE_ITER_ATTR) {
+                                       node = NULL;
+                               }
+
+                               if (node) {
+                                       node = node->next;
+                               }
+
+                               prefix = sxe->iter.nsprefix;
+
+                               while (node && nodendx < Z_TYPE_P(member)) {
+                                       SKIP_TEXT(node)
+                                       if (node->type == XML_ELEMENT_NODE) {
+                                               if (match_ns(sxe, node, prefix)) {
+                                                       if (sxe->iter.type == SXE_ITER_ELEMENT && !xmlStrcmp(node->name, sxe->iter.name)) {
+                                                               nodendx++;
+                                                               if (nodendx == Z_TYPE_P(member)) {
+                                                                       break;
+                                                               }
+                                                       }
+                                               } else {
                                                        break;
                                                }
                                        }
-                                       
-                                       if (match_ns(sxe, node, name)) {
-                                               APPEND_PREV_ELEMENT(counter, value);
-                                               MAKE_STD_ZVAL(value);
-                                               _node_as_zval(sxe, node->parent, value TSRMLS_CC);
-                                               APPEND_CUR_ELEMENT(counter, value);
-                                               goto next_iter;
-                                       }
-                               } while (0);
-       
-                               if (!xmlStrcmp(node->name, name)) {
-                                       APPEND_PREV_ELEMENT(counter, value);
-                                       MAKE_STD_ZVAL(value);
-                                       _node_as_zval(sxe, node, value TSRMLS_CC);
-                                       APPEND_CUR_ELEMENT(counter, value);
+                       next_iter:
+                                       node = node->next;
                                }
-       
-next_iter:
-                               node = node->next;
+                               if (node) {
+                                       _node_as_zval(sxe, node, return_value, SXE_ITER_NONE, NULL, NULL TSRMLS_CC);
+                               }
+                       } else {
+                               _node_as_zval(sxe, node, return_value, SXE_ITER_ELEMENT, name, sxe->iter.nsprefix TSRMLS_CC);
                        }
                }
-
-               /* Only one value found */
-               if (counter == 1) {
-                       SEPARATE_ZVAL(&value);
-                       zval_dtor(return_value);
-                       FREE_ZVAL(return_value); 
-                       return_value = value;
-               }
        }
 
        return_value->refcount = 0;
@@ -290,9 +308,10 @@ static void sxe_prop_dim_write(zval *object, zval *member, zval *value, zend_boo
        xmlNodePtr      node;
        xmlNodePtr      newnode = NULL;
        xmlNodePtr              tempnode;
-       xmlAttrPtr      attrptr, attr = NULL;
+       xmlAttrPtr      attr = NULL;
        int             counter = 0;
        int             is_attr = 0;
+       int                             itercount = 0;
        zval            tmp_zv, trim_zv;
 
        if (!member) {
@@ -304,14 +323,21 @@ static void sxe_prop_dim_write(zval *object, zval *member, zval *value, zend_boo
                return;
        }
 
-       if (Z_TYPE_P(member) != IS_STRING) {
-               trim_zv = *member;
-               zval_copy_ctor(&trim_zv);
-               convert_to_string(&trim_zv);
-               php_trim(Z_STRVAL(trim_zv), Z_STRLEN(trim_zv), NULL, 0, &tmp_zv, 3 TSRMLS_CC);
-               zval_dtor(&trim_zv);
-               member = &tmp_zv;
-       }
+       if (Z_TYPE_P(member) == IS_LONG) {
+               if (Z_LVAL_P(member) == 0) {
+                       elements = 1;
+                       attribs = 0;
+               } else
+                       return;
+       } else
+               if (Z_TYPE_P(member) != IS_STRING) {
+                       trim_zv = *member;
+                       zval_copy_ctor(&trim_zv);
+                       convert_to_string(&trim_zv);
+                       php_trim(Z_STRVAL(trim_zv), Z_STRLEN(trim_zv), NULL, 0, &tmp_zv, 3 TSRMLS_CC);
+                       zval_dtor(&trim_zv);
+                       member = &tmp_zv;
+               }
 
        if (!Z_STRLEN_P(member)) {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot write or create unnamed %s", attribs ? "attribute" : "element");
@@ -325,45 +351,40 @@ static void sxe_prop_dim_write(zval *object, zval *member, zval *value, zend_boo
        sxe = php_sxe_fetch_object(object TSRMLS_CC);
 
        GET_NODE(sxe, node);
+       node = php_sxe_get_first_node(sxe, node TSRMLS_CC);
 
        if (node) {
                if (attribs) {
-                       xmlChar *localname, *prefix=NULL;
-                       localname = xmlSplitQName2(name, &prefix);
-                       if (localname == NULL) {
-                               localname = (xmlChar *)name;
-                       }
-                       attrptr = node->properties;
-                       while (attrptr) {
-                               if (!xmlStrcmp(attrptr->name, localname) && (prefix==NULL || 
-                                       (attrptr->ns && (!xmlStrcmp(attrptr->ns->prefix, prefix) || match_ns(sxe, (xmlNodePtr) attrptr, prefix))))) {
-
-                                       attr = attrptr;
+                       attr = node->properties;
+                       while (attr) {
+                               if (!xmlStrcmp(attr->name, name) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix)) {
                                        is_attr = 1;
                                        ++counter;
+                                       break;
                                }
-       
-                               attrptr = attrptr->next;
-                       }
-                       if (prefix) {
-                               xmlFree(prefix);
-                               if (localname) {
-                                       xmlFree(localname);
-                               }
+                               attr = attr->next;
                        }
+
                }
 
                if (elements) {
-                       node = node->children;
-                       while (node) {
-                               SKIP_TEXT(node);
-                               if (!xmlStrcmp(node->name, name)) {
-                                       newnode = node;
-                                       ++counter;
-                               }
-       
+                       if (Z_TYPE_P(member) == IS_LONG) {
+                               newnode = node;
+                               ++counter;
+                       } else {
+                               node = node->children;
+                               while (node) {
+                                       SKIP_TEXT(node);
+
+                                       if (!xmlStrcmp(node->name, name)) {
+                                               newnode = node;
+                                               ++counter;
+                                       }
+               
 next_iter:
-                               node = node->next;
+                                       itercount++;
+                                       node = node->next;
+                               }
                        }
                }
 
@@ -433,28 +454,15 @@ static int sxe_prop_dim_exists(zval *object, zval *member, int check_empty, zend
 
        if (node) {
                if (attribs) {
-                       xmlChar *localname, *prefix=NULL;
-                       localname = xmlSplitQName2(name, &prefix);
-                       if (localname == NULL) {
-                               localname = (xmlChar *)name;
-                       }
                        attr = node->properties;
                        while (attr) {
-                               if (!xmlStrcmp(attr->name, localname) && (prefix==NULL || 
-                                       (attr->ns && (!xmlStrcmp(attr->ns->prefix, prefix) || match_ns(sxe, (xmlNodePtr) attr, prefix))))) {
-
+                               if (!xmlStrcmp(attr->name, name) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix)) {
                                        exists = 1;
                                        break;
                                }
        
                                attr = attr->next;
                        }
-                       if (prefix) {
-                               xmlFree(prefix);
-                               if (localname) {
-                                       xmlFree(localname);
-                               }
-                       }
                }
 
                if (elements) {
@@ -513,32 +521,20 @@ static void sxe_prop_dim_delete(zval *object, zval *member, zend_bool elements,
        sxe = php_sxe_fetch_object(object TSRMLS_CC);
 
        GET_NODE(sxe, node);
+       node = php_sxe_get_first_node(sxe, node TSRMLS_CC);
 
        if (node) {
                if (attribs) {
-
-                       xmlChar *localname, *prefix=NULL;
-                       localname = xmlSplitQName2(Z_STRVAL_P(member), &prefix);
-                       if (localname == NULL) {
-                               localname = (xmlChar *)Z_STRVAL_P(member);
-                       }
                        attr = node->properties;
                        while (attr) {
                                anext = attr->next;
-                               if (!xmlStrcmp(attr->name, localname) && (prefix==NULL || 
-                                       (attr->ns && (!xmlStrcmp(attr->ns->prefix, prefix) || match_ns(sxe, (xmlNodePtr) attr, prefix))))) {
-
+                               if (!xmlStrcmp(attr->name, Z_STRVAL_P(member)) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix)) {
                                        xmlUnlinkNode((xmlNodePtr) attr);
                                        php_libxml_node_free_resource((xmlNodePtr) attr TSRMLS_CC);
+                                       break;
                                }
                                attr = anext;
                        }
-                       if (prefix) {
-                               xmlFree(prefix);
-                               if (localname) {
-                                       xmlFree(localname);
-                               }
-                       }
                }
 
                if (elements) {
@@ -639,6 +635,7 @@ sxe_properties_get(zval *object TSRMLS_DC)
        }
 
        GET_NODE(sxe, node);
+       node = php_sxe_get_first_node(sxe, node TSRMLS_CC);
 
        if (node) {
                node = node->children;
@@ -725,9 +722,9 @@ simplexml_ce_xpath_register_ns(char *prefix, xmlXPathContext *xpath, char *href)
 /* }}} */
 
 
-/* {{{ xsearch()
+/* {{{ xpath()
  */ 
-SXE_METHOD(xsearch)
+SXE_METHOD(xpath)
 {
        php_sxe_object    *sxe;
        zval              *value;
@@ -801,9 +798,9 @@ SXE_METHOD(xsearch)
                         * to the parent node.
                         */
                        if (nodeptr->type == XML_TEXT_NODE) {
-                               _node_as_zval(sxe, nodeptr->parent, value TSRMLS_CC);
+                               _node_as_zval(sxe, nodeptr->parent, value, SXE_ITER_NONE, NULL, NULL TSRMLS_CC);
                        } else  {
-                               _node_as_zval(sxe, nodeptr, value TSRMLS_CC);
+                               _node_as_zval(sxe, nodeptr, value, SXE_ITER_NONE, NULL, NULL TSRMLS_CC);
                        }
 
                        add_next_index_zval(return_value, value);
@@ -814,99 +811,6 @@ SXE_METHOD(xsearch)
 }
 /* }}} */
 
-#define SCHEMA_FILE 0
-#define SCHEMA_BLOB 1
-#define SCHEMA_OBJECT 2
-
-#ifdef LIBXML_SCHEMAS_ENABLED
-
-/* {{{ simplexml_ce_schema_validate_file()
- */
-static void
-simplexml_ce_schema_validate(INTERNAL_FUNCTION_PARAMETERS, int type)
-{
-       php_sxe_object         *sxe;
-       zval                   **source;
-       xmlSchemaParserCtxtPtr  parser;
-       xmlSchemaPtr            sptr;
-       xmlSchemaValidCtxtPtr   vptr;
-       
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &source) == FAILURE) {
-               return;
-       }
-
-       sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
-
-       switch (type) {
-               case SCHEMA_FILE:
-                       convert_to_string_ex(source);
-                       parser = xmlSchemaNewParserCtxt(Z_STRVAL_PP(source));
-                       if (parser == NULL) {
-                               php_error_docref1(NULL TSRMLS_CC, Z_STRVAL_PP(source), E_WARNING, "Unable to load XML Schema file");
-                               RETURN_FALSE;
-                       }
-                       sptr = xmlSchemaParse(parser);
-                       break;
-               case SCHEMA_BLOB:
-                       convert_to_string_ex(source);
-                       parser = xmlSchemaNewMemParserCtxt(Z_STRVAL_PP(source), Z_STRLEN_PP(source));
-                       sptr = xmlSchemaParse(parser);
-                       break;
-               default:
-                       parser = NULL;
-                       sptr = NULL;
-       }
-
-       if (sptr == NULL) {
-               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Malformed XML Schema");
-               xmlSchemaFreeParserCtxt(parser);
-               RETURN_FALSE;
-       }
-
-       vptr = xmlSchemaNewValidCtxt(sptr);
-
-       if (vptr == NULL) {
-               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create XML Schema validation context");
-               xmlSchemaFree(sptr);
-               xmlSchemaFreeParserCtxt(parser);
-               RETURN_FALSE;
-       }
-
-       switch (xmlSchemaValidateDoc(vptr, (xmlDocPtr) sxe->document->ptr)) {
-               case 0: /* validated */
-                       RETVAL_TRUE;
-                       break;
-               case -1: /* internal error */
-                       RETVAL_FALSE;
-                       break;
-               default: /* error */
-                       RETVAL_FALSE;
-                       break;
-       }
-
-       xmlSchemaFree(sptr);
-       xmlSchemaFreeValidCtxt(vptr);
-       xmlSchemaFreeParserCtxt(parser);
-}
-/* }}} */
-
-/* {{{ validate_schema_file
- */
-SXE_METHOD(validate_schema_file)
-{
-       simplexml_ce_schema_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, SCHEMA_FILE);
-}
-/* }}} */
-
-/* {{{ validate_schema_buffer
- */
-SXE_METHOD(validate_schema_buffer)
-{
-       simplexml_ce_schema_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, SCHEMA_BLOB);
-}
-/* }}} */
-#endif
-
 /* {{{ simplexml_ce_register_ns()
  */
 SXE_METHOD(register_ns)
@@ -927,14 +831,26 @@ SXE_METHOD(register_ns)
 }
 /* }}} */
 
-/* {{{ simplexml_ce_to_xml_string()
+/* {{{ proto asXML([string filename])
  */
-SXE_METHOD(to_xml_string)
+SXE_METHOD(asXML)
 {
        php_sxe_object *sxe;
        xmlChar *strval;
+       char           *filename;
+       int             filename_len;
 
-
+       if (ZEND_NUM_ARGS() == 1) {
+               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) {
+                       RETURN_FALSE;
+               }
+       
+               sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
+       
+               xmlSaveFile(filename, (xmlDocPtr) sxe->document->ptr);
+       
+               RETURN_TRUE;
+       }
        if (ZEND_NUM_ARGS() != 0) {
                RETURN_FALSE;
        }
@@ -948,23 +864,25 @@ SXE_METHOD(to_xml_string)
 }
 /* }}} */
 
-/* {{{ simplexml_ce_to_xml_file()
+/* {{{ simplexml_children()
  */
-SXE_METHOD(to_xml_file)
+SXE_METHOD(children)
 {
        php_sxe_object *sxe;
-       char           *filename;
-       int             filename_len;
-       
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) {
+       char           *nsprefix = NULL;
+       int             nsprefix_len;
+       xmlNodePtr      node;
+
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!", &nsprefix, &nsprefix_len) == FAILURE) {
                return;
        }
 
        sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
+       GET_NODE(sxe, node);
+       node = php_sxe_get_first_node(sxe, node TSRMLS_CC);
 
-       xmlSaveFile(filename, (xmlDocPtr) sxe->document->ptr);
+       _node_as_zval(sxe, node, return_value, SXE_ITER_CHILD, NULL, nsprefix TSRMLS_CC);
 
-       RETURN_TRUE;
 }
 /* }}} */
 
@@ -973,36 +891,19 @@ SXE_METHOD(to_xml_file)
 SXE_METHOD(attributes)
 {
        php_sxe_object *sxe;
+       char           *nsprefix = NULL;
+       int             nsprefix_len;
        xmlNodePtr      node;
-       xmlAttrPtr      attr;
-       zval           *value = NULL;
-       char           *contents;
 
-       if (ZEND_NUM_ARGS() != 0) {
-               RETURN_FALSE;
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!", &nsprefix, &nsprefix_len) == FAILURE) {
+               return;
        }
 
        sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
        GET_NODE(sxe, node);
+       node = php_sxe_get_first_node(sxe, node TSRMLS_CC);
 
-       array_init(return_value);
-       if (node) {
-               attr = node->properties;
-               while (attr) {
-                       if (attr->name) {
-                               MAKE_STD_ZVAL(value);
-                               contents = xmlNodeListGetString((xmlDocPtr) sxe->document->ptr, attr->children, 1);
-                               ZVAL_STRING(value, contents, 1);
-                               if (contents) {
-                                       xmlFree(contents);
-                               }
-                               add_assoc_zval_ex(return_value,
-                                       (char*)attr->name,
-                                       xmlStrlen(attr->name) + 1, value);
-                       }
-                       attr = attr->next;
-               }
-       }
+       _node_as_zval(sxe, node, return_value, SXE_ITER_ATTRLIST, NULL, nsprefix TSRMLS_CC);
 }
 /* }}} */
 
@@ -1046,25 +947,34 @@ sxe_object_cast(zval *readobj, zval *writeobj, int type, int should_free TSRMLS_
 {
        php_sxe_object *sxe;
        char           *contents = NULL;
+       xmlNodePtr          node;
        zval free_obj;
        int rv;
 
        sxe = php_sxe_fetch_object(readobj TSRMLS_CC);
+
        if (should_free) {
                free_obj = *writeobj;
        }
 
-       if (!sxe->node) {
-               if (sxe->document) {
-                       php_libxml_increment_node_ptr((php_libxml_node_object *)sxe, xmlDocGetRootElement((xmlDocPtr) sxe->document->ptr), NULL TSRMLS_CC);
+       if (sxe->iter.type != SXE_ITER_NONE) {
+               node = php_sxe_get_first_node(sxe, NULL TSRMLS_CC);
+               if (node) {
+                       contents = xmlNodeListGetString((xmlDocPtr) sxe->document->ptr, node->children, 1);
+               }
+       } else {
+               if (!sxe->node) {
+                       if (sxe->document) {
+                               php_libxml_increment_node_ptr((php_libxml_node_object *)sxe, xmlDocGetRootElement((xmlDocPtr) sxe->document->ptr), NULL TSRMLS_CC);
+                       }
                }
-       }
 
-       if (sxe->node && sxe->node->node) {
-               if (sxe->node->node->children) {
-                       contents = xmlNodeListGetString((xmlDocPtr) sxe->document->ptr, sxe->node->node->children, 1);
+               if (sxe->node && sxe->node->node) {
+                       if (sxe->node->node->children) {
+                               contents = xmlNodeListGetString((xmlDocPtr) sxe->document->ptr, sxe->node->node->children, 1);
+                       }
                }
-       } 
+       }
 
        rv = cast_object(writeobj, type, contents TSRMLS_CC);
 
@@ -1154,6 +1064,13 @@ static void sxe_object_dtor(void *object, zend_object_handle handle TSRMLS_DC)
                zval_ptr_dtor(&sxe->iter.data);
        }
 
+       if (sxe->iter.name) {
+               xmlFree(sxe->iter.name);
+       }
+       if (sxe->iter.nsprefix) {
+               xmlFree(sxe->iter.nsprefix);
+       }
+
        php_libxml_node_decrement_resource((php_libxml_node_object *)sxe TSRMLS_CC);
 
        if (sxe->nsmapptr && --sxe->nsmapptr->refcount == 0) {
@@ -1236,7 +1153,7 @@ PHP_FUNCTION(simplexml_load_file)
        if (! docp) {
                RETURN_FALSE;
        }
-       
+
        if (classname_len) {
                zend_class_entry **pce;
                if (zend_lookup_class(classname, classname_len, &pce TSRMLS_CC) == FAILURE) {
@@ -1291,6 +1208,7 @@ PHP_FUNCTION(simplexml_load_string)
        sxe->nsmapptr = emalloc(sizeof(simplexml_nsmap));
        sxe->nsmapptr->nsmap = xmlHashCreate(10);
        sxe->nsmapptr->refcount = 1;
+       sxe->iter.type = SXE_ITER_NONE;
        php_libxml_increment_node_ptr((php_libxml_node_object *)sxe, xmlDocGetRootElement(docp), NULL TSRMLS_CC);
 
        return_value->type = IS_OBJECT;
@@ -1347,29 +1265,65 @@ zend_object_iterator_funcs php_sxe_iterator_funcs = {
        php_sxe_iterator_rewind,
 };
 
-static void php_sxe_iterator_current(php_sxe_object *sxe TSRMLS_DC)
+static void php_sxe_reset_iterator(php_sxe_object *sxe TSRMLS_DC)
 {
-       xmlNodePtr      node;
+       xmlNodePtr node;
+       char *prefix;
 
        if (sxe->iter.data) {
                zval_ptr_dtor(&sxe->iter.data);
+               sxe->iter.data = NULL;
+       }
+
+       GET_NODE(sxe, node)
+
+       if (node) {
+               switch (sxe->iter.type) {
+                       case SXE_ITER_ELEMENT:
+                       case SXE_ITER_CHILD:
+                       case SXE_ITER_NONE:
+                               node = node->children;
+                               break;
+                       case SXE_ITER_ATTR:
+                       case SXE_ITER_ATTRLIST:
+                               node = (xmlNodePtr) node->properties;
+               }
        }
-       ALLOC_INIT_ZVAL(sxe->iter.data);
-       while (sxe->iter.node) {
-               node = sxe->iter.node;
 
+       prefix = sxe->iter.nsprefix;
+
+       while (node) {
                SKIP_TEXT(node);
-       
-               if (!sxe->iter.node->name) {
-                       goto next_iter;
+               if (sxe->iter.type != SXE_ITER_ATTR && sxe->iter.type != SXE_ITER_ATTRLIST && node->type == XML_ELEMENT_NODE) {
+                       if (sxe->iter.type == SXE_ITER_ELEMENT) { 
+                               if (!xmlStrcmp(node->name, sxe->iter.name) && match_ns(sxe, node, prefix)) {
+                                       break;
+                               }
+                       } else {
+                               if (match_ns(sxe, node, prefix)) {
+                                       break;
+                               }
+                       }
                } else {
-                       sxe->iter.namelen = xmlStrlen(node->name)+1;
-                       sxe->iter.name = (char *) node->name;
-                       _node_as_zval(sxe, node, sxe->iter.data TSRMLS_CC);
+                       if (node->type == XML_ATTRIBUTE_NODE) {
+                               if (sxe->iter.type == SXE_ITER_ATTR) {
+                                       if (!xmlStrcmp(node->name, sxe->iter.name) && match_ns(sxe, node, sxe->iter.nsprefix)) {
+                                               break;
+                                       }
+                               } else {
+                                       if (match_ns(sxe, node, sxe->iter.nsprefix)) {
+                                               break;
+                                       }
+                               }
+                       }
                }
-               break;
 next_iter:
-               sxe->iter.node = sxe->iter.node->next;
+               node = node->next;
+       }
+
+       if (node) {
+               ALLOC_INIT_ZVAL(sxe->iter.data);
+               _node_as_zval(sxe, node, sxe->iter.data, SXE_ITER_NONE, NULL, NULL TSRMLS_CC);
        }
 }
 
@@ -1398,7 +1352,7 @@ static int php_sxe_iterator_has_more(zend_object_iterator *iter TSRMLS_DC)
 {
        php_sxe_iterator *iterator = (php_sxe_iterator *)iter;
 
-       return iterator->sxe->iter.node ? SUCCESS : FAILURE;
+       return iterator->sxe->iter.data ? SUCCESS : FAILURE;
 }
 
 static void php_sxe_iterator_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC)
@@ -1410,32 +1364,95 @@ static void php_sxe_iterator_current_data(zend_object_iterator *iter, zval ***da
 
 static int php_sxe_iterator_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC)
 {
+       zval *curobj;
+       xmlNodePtr curnode = NULL;
+       php_sxe_object *intern;
+       int namelen;
+
        php_sxe_iterator *iterator = (php_sxe_iterator *)iter;
-       
-       *str_key = estrndup(iterator->sxe->iter.name, iterator->sxe->iter.namelen-1);
-       *str_key_len = iterator->sxe->iter.namelen;
+       curobj = iterator->sxe->iter.data;
+
+       intern = (php_sxe_object *)zend_object_store_get_object(curobj TSRMLS_CC);
+       if (intern != NULL && intern->node != NULL) {
+               curnode = (xmlNodePtr)((php_libxml_node_ptr *)intern->node)->node;
+       }
+
+       namelen = xmlStrlen(curnode->name);
+       *str_key = estrndup(curnode->name, namelen);
+       *str_key_len = namelen + 1;
        return HASH_KEY_IS_STRING;
+
 }
 
 static void php_sxe_iterator_move_forward(zend_object_iterator *iter TSRMLS_DC)
 {
+       xmlNodePtr      node;
+       php_sxe_object  *intern;
+       php_sxe_object  *sxe;
+       char *prefix;
+
        php_sxe_iterator *iterator = (php_sxe_iterator *)iter;
+       sxe = iterator->sxe;
+
+       if (sxe->iter.data) {
+               intern = (php_sxe_object *)zend_object_store_get_object(sxe->iter.data TSRMLS_CC);
+               GET_NODE(intern, node)
+               zval_ptr_dtor(&sxe->iter.data);
+               sxe->iter.data = NULL;
+       } else {
+               node = sxe->iter.node->node;
+       }
+
+       if (node) {
+               node = node->next;
+       }
+
+       prefix = sxe->iter.nsprefix;
+
+       while (node) {
+               SKIP_TEXT(node);
+
+               if (sxe->iter.type != SXE_ITER_ATTR && sxe->iter.type != SXE_ITER_ATTRLIST && node->type == XML_ELEMENT_NODE) {
+                       if (sxe->iter.type == SXE_ITER_ELEMENT) { 
+                               if (!xmlStrcmp(node->name, sxe->iter.name) && match_ns(sxe, node, prefix)) {
+                                       break;
+                               }
+                       } else {
+                               if (match_ns(sxe, node, prefix)) {
+                                       break;
+                               }
+                       }
+               } else {
+                       if (node->type == XML_ATTRIBUTE_NODE) {
+                               if (sxe->iter.type == SXE_ITER_ATTR) {
+                                       if (!xmlStrcmp(node->name, sxe->iter.name) && match_ns(sxe, node, sxe->iter.nsprefix)) {
+                                               break;
+                                       }
+                               } else {
+                                       if (match_ns(sxe, node, sxe->iter.nsprefix)) {
+                                               break;
+                                       }
+                               }
+                       }
+               }
+next_iter:
+               node = node->next;
+       }
 
-       if (iterator->sxe->iter.node) {
-               iterator->sxe->iter.node = iterator->sxe->iter.node->next;
+       if (node) {
+               ALLOC_INIT_ZVAL(sxe->iter.data);
+               _node_as_zval(sxe, node, sxe->iter.data, SXE_ITER_NONE, NULL, NULL TSRMLS_CC);
        }
-       php_sxe_iterator_current(iterator->sxe TSRMLS_CC);
 }
 
 static void php_sxe_iterator_rewind(zend_object_iterator *iter TSRMLS_DC)
 {
+       php_sxe_object  *sxe;
+
        php_sxe_iterator *iterator = (php_sxe_iterator *)iter;
-       
-       GET_NODE(iterator->sxe, iterator->sxe->iter.node);
-       if (iterator->sxe->iter.node) {
-               iterator->sxe->iter.node = iterator->sxe->iter.node->children;
-       }
-       php_sxe_iterator_current(iterator->sxe TSRMLS_CC);
+       sxe = iterator->sxe;
+
+       php_sxe_reset_iterator(sxe TSRMLS_CC);
 }
 
 
@@ -1528,14 +1545,10 @@ ZEND_GET_MODULE(simplexml)
 static zend_function_entry sxe_functions[] = {
        SXE_ME(__construct,            NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) /* must be called */
        SXE_ME(register_ns,            NULL, ZEND_ACC_PUBLIC)
-       SXE_ME(to_xml_file,            NULL, ZEND_ACC_PUBLIC)
-       SXE_ME(to_xml_string,          NULL, ZEND_ACC_PUBLIC)
-#ifdef LIBXML_SCHEMAS_ENABLED
-       SXE_ME(validate_schema_buffer, NULL, ZEND_ACC_PUBLIC)
-       SXE_ME(validate_schema_file,   NULL, ZEND_ACC_PUBLIC)
-#endif
-       SXE_ME(xsearch,                NULL, ZEND_ACC_PUBLIC)
+       SXE_ME(asXML,                  NULL, ZEND_ACC_PUBLIC)
+       SXE_ME(xpath,                  NULL, ZEND_ACC_PUBLIC)
        SXE_ME(attributes,             NULL, ZEND_ACC_PUBLIC)
+       SXE_ME(children,                           NULL, ZEND_ACC_PUBLIC)
        {NULL, NULL, NULL}
 };
 
index 01ee3f45dd1d2dbff52cb538d1d6e8a580082654..9e81f20dd9c05bce5c073df6356132e97c47a52f 100755 (executable)
@@ -72,11 +72,9 @@ string(10) "Bla bla 1."
 string(6) "elem11"
 string(10) "Bla bla 2."
 ===ELEMENT===
-string(7) "elem111"
-string(7) "Foo Bar"
+string(6) "elem11"
+string(10) "Bla bla 2."
 ===COMMENT===
-string(7) "comment"
-string(0) ""
-string(5) "elem2"
-string(28) "Here we have some text data."
+string(5) "elem1"
+string(10) "Bla bla 1."
 ===DONE===
index f37d5c2316260b01320ff8c54a744847eca66800..c7f3fc18492c8f1824832fc3a683e25d4fc0bd2a 100755 (executable)
@@ -49,11 +49,23 @@ object(simplexml_element)#%d (2) {
   }
 }
 ===Array===
-string(5) "elem1"
-string(5) "first"
+object(simplexml_element)#2 (1) {
+  [0]=>
+  string(5) "elem1"
+}
+object(simplexml_element)#6 (1) {
+  [0]=>
+  string(5) "first"
+}
 ===Set===
-string(8) "Changed1"
-string(2) "12"
+object(simplexml_element)#6 (1) {
+  [0]=>
+  string(8) "Changed1"
+}
+object(simplexml_element)#5 (1) {
+  [0]=>
+  string(2) "12"
+}
 ===Unset===
 NULL
 NULL
index 14912a6673fb06ca925e4279430dee363c687b74..1726726a1a86c6f031b36edd36074d53a4da781c 100644 (file)
@@ -5,8 +5,8 @@ SimpleXML and XPath
 --FILE--
 <?php 
 $sxe = simplexml_load_file(dirname(__FILE__).'/sxe.xml');
-var_dump($sxe->xsearch("elem1/elem2/elem3/elem4"));
-var_dump($sxe->xsearch("***"));
+var_dump($sxe->xpath("elem1/elem2/elem3/elem4"));
+var_dump($sxe->xpath("***"));
 ?>
 --EXPECTF--
 array(1) {
index 9b6bf154179ef45ed9df68a24327873afaa7e13c..f48c9f1eecaa0fca435ce8bafbcf05a5b534c779 100755 (executable)
@@ -39,7 +39,7 @@ echo "\n";
 ===BAR===
 bar
 ===BAZ===
-Array
+baz1
 ===BAZ0===
 baz1
 ===BAZ1===
index cd8d85e9ec89a9cb9f71d1dced7ebef55211fe30..79c01107fe8768d1b7595af5f41f2b49e6104583 100755 (executable)
@@ -18,11 +18,11 @@ $sxe = simplexml_load_string($xml);
 $sxe[""] = "warning";
 $sxe["attr"] = "value";
 
-echo $sxe->to_xml_string();
+echo $sxe->asXML();
 
 $sxe["attr"] = "new value";
 
-echo $sxe->to_xml_string();
+echo $sxe->asXML();
 
 $sxe[] = "error";
 
index 13fe42b96ce497d0b51d5a2ab14d185ddef9c20e..4c559d8a159be03f79419f08770458520788f321 100644 (file)
@@ -18,23 +18,40 @@ $person['name'] = "XXX";
 var_dump($people->person['name']);
 $people->person['age'] = 30;
 var_dump($people->person['age']);
-$people->person['age'] += 5;
-var_dump($people->person['age']);
 echo "---Unset:---\n";
 unset($people->person['age']);
 echo "---Unset?---\n";
 var_dump($people->person['age']);
 var_dump(isset($people->person['age']));
-echo "---Done---\n";
+$people->person['age'] = 30;
+echo "---Unsupported---\n";
+var_dump($people->person['age']);
+$people->person['age'] += 5;
+var_dump($people->person['age']);
 ?>
---EXPECT--
-string(3) "Joe"
+===DONE===
+--EXPECTF--
+object(simplexml_element)#%d (1) {
+  [0]=>
+  string(3) "Joe"
+}
 NULL
-string(3) "XXX"
-string(2) "30"
-string(2) "35"
+object(simplexml_element)#%d (1) {
+  [0]=>
+  string(3) "XXX"
+}
+object(simplexml_element)#%d (1) {
+  [0]=>
+  string(2) "30"
+}
 ---Unset:---
 ---Unset?---
 NULL
 bool(false)
----Done---
+---Unsupported---
+object(simplexml_element)#%d (1) {
+  [0]=>
+  string(2) "30"
+}
+
+Fatal error: Unsupported operand types in %s014.php on line %d
index 895917f6cee07ee0497d5ef71830c2aba68588a9..5f2e15a74fe485569456cf9986791f9eee4c8126 100755 (executable)
@@ -18,23 +18,39 @@ $person['name'] = "XXX";
 var_dump($people->person[0]['name']);
 $people->person[0]['age'] = 30;
 var_dump($people->person[0]['age']);
-$people->person[0]['age'] += 5;
-var_dump($people->person[0]['age']);
 echo "---Unset:---\n";
 unset($people->person[0]['age']);
 echo "---Unset?---\n";
 var_dump($people->person[0]['age']);
 var_dump(isset($people->person[0]['age']));
-echo "---Done---\n";
+echo "---Unsupported---\n";
+var_dump($people->person[0]['age']);
+$people->person['age'] += 5;
+var_dump($people->person[0]['age']);
 ?>
---EXPECT--
-string(3) "Joe"
+===DONE===
+--EXPECTF--
+object(simplexml_element)#%d (1) {
+  [0]=>
+  string(3) "Joe"
+}
 NULL
-string(3) "XXX"
-string(2) "30"
-string(2) "35"
+object(simplexml_element)#%d (1) {
+  [0]=>
+  string(3) "XXX"
+}
+object(simplexml_element)#%d (1) {
+  [0]=>
+  string(2) "30"
+}
 ---Unset:---
 ---Unset?---
 NULL
 bool(false)
----Done---
+---Unsupported---
+object(simplexml_element)#%d (1) {
+  [0]=>
+  string(2) "30"
+}
+
+Fatal error: Unsupported operand types in %s014.php on line %d
index 63882d01e7716fdb498427a0bb1727f9c5148eff..2452a1468c14683379d61ed2449bbe8399a4f1a6 100755 (executable)
@@ -19,23 +19,38 @@ $person['name'] = "XXX";
 var_dump($people->person[1]['name']);
 $people->person[1]['age'] = 30;
 var_dump($people->person[1]['age']);
-$people->person[1]['age'] += 5;
-var_dump($people->person[1]['age']);
 echo "---Unset:---\n";
 unset($people->person[1]['age']);
 echo "---Unset?---\n";
 var_dump($people->person[1]['age']);
 var_dump(isset($people->person[1]['age']));
-echo "---Done---\n";
+echo "---Unsupported---\n";
+$people->person[1]['age'] += 5;
+var_dump($people->person[1]['age']);
 ?>
---EXPECT--
-string(3) "Joe"
+===DONE===
+--EXPECTF--
+object(simplexml_element)#%d (1) {
+  [0]=>
+  string(3) "Joe"
+}
 NULL
-string(3) "XXX"
-string(2) "30"
-string(2) "35"
+object(simplexml_element)#%d (1) {
+  [0]=>
+  string(3) "XXX"
+}
+object(simplexml_element)#%d (1) {
+  [0]=>
+  string(2) "30"
+}
 ---Unset:---
 ---Unset?---
 NULL
 bool(false)
----Done---
+---Unsupported---
+object(simplexml_element)#%d (1) {
+  [0]=>
+  string(2) "30"
+}
+
+Fatal error: Unsupported operand types in %s014.php on line %d
index 240c8f5b6b65ccf28e6b8e888657814753759160..b134354d79646ed920e9e0d7597721680dfd1be3 100644 (file)
@@ -34,11 +34,23 @@ var_dump($people->person[0]['name']);
 $people = simplexml_load_string($xml2);
 var_dump($people->person[0]['name']);
 var_dump($people->person[1]['name']);
-echo "---Done---\n";
 ?>
+===DONE===
 --EXPECT--
-string(3) "Joe"
-string(3) "Joe"
-string(3) "Joe"
-string(3) "Boe"
----Done---
+object(simplexml_element)#4 (1) {
+  [0]=>
+  string(3) "Joe"
+}
+object(simplexml_element)#3 (1) {
+  [0]=>
+  string(3) "Joe"
+}
+object(simplexml_element)#2 (1) {
+  [0]=>
+  string(3) "Joe"
+}
+object(simplexml_element)#2 (1) {
+  [0]=>
+  string(3) "Boe"
+}
+===DONE===
index 9f886312221639f4af5254a84eb86bc9881347ec..ce197d4a63fc82365a9de920bd94a1922a83c30e 100644 (file)
@@ -26,14 +26,32 @@ var_dump($people->person[0]['name']);
 $people->person[0]['name'] .= 'Bar';
 var_dump($people->person[0]['name']);
 
-echo "---Done---\n";
 ?>
+===DONE===
 --EXPECT--
-string(3) "Joe"
-string(6) "JoeFoo"
-string(9) "JoeFooBar"
+object(simplexml_element)#4 (1) {
+  [0]=>
+  string(3) "Joe"
+}
+object(simplexml_element)#2 (1) {
+  [0]=>
+  string(6) "JoeFoo"
+}
+object(simplexml_element)#5 (1) {
+  [0]=>
+  string(9) "JoeFooBar"
+}
 ---[0]---
-string(3) "Joe"
-string(6) "JoeFoo"
-string(9) "JoeFooBar"
----Done---
+object(simplexml_element)#3 (1) {
+  [0]=>
+  string(3) "Joe"
+}
+object(simplexml_element)#2 (1) {
+  [0]=>
+  string(6) "JoeFoo"
+}
+object(simplexml_element)#5 (1) {
+  [0]=>
+  string(9) "JoeFooBar"
+}
+===Done===
index 355ac5f599aa78f1b86ca7901c211791a96d3ef5..776b00c78544076ae1928a2021bd172f604e3017 100644 (file)
@@ -25,52 +25,62 @@ $xml1 =<<<EOF
 EOF;
 
 function print_xml($xml) {
-  foreach($xml as $person) {
+  foreach($xml->children() as $person) {
     echo "person: ".$person['name']."\n";
-    foreach($person as $child) {
+    foreach($person->children() as $child) {
       echo "  child: ".$child['name']."\n";
     }
   }
-  echo "----------\n";
 }
 
 function print_xml2($xml) {
-  $persons = count($xml->person);
+  $persons = 2;
   for ($i=0;$i<$persons;$i++) {
     echo "person: ".$xml->person[$i]['name']."\n";
-       $children = count($xml->person[$i]->child);
+       $children = 2;
     for ($j=0;$j<$children;$j++) {
       echo "  child: ".$xml->person[$i]->child[$j]['name']."\n";
     }
   }
-  echo "----------\n";
 }
 
+echo "---11---\n";
 print_xml(simplexml_load_string($xml));
+echo "---12---\n";
 print_xml(simplexml_load_string($xml1));
+echo "---21---\n";
 print_xml2(simplexml_load_string($xml));
+echo "---22---\n";
 print_xml2(simplexml_load_string($xml1));
-echo "---Done---\n";
 ?>
---EXPECT--
+===DONE===
+--EXPECTF--
+---11---
 person: Joe
   child: Ann
   child: Marray
 person: Boe
   child: Joe
   child: Ann
-----------
+---12---
 person: Joe
   child: Ann
-----------
+---21---
 person: Joe
   child: Ann
   child: Marray
 person: Boe
   child: Joe
   child: Ann
-----------
+---22---
 person: Joe
   child: Ann
-----------
----Done---
+  child: 
+person: 
+
+Notice: Trying to get property of non-object in %s017.php on line %d
+  child: 
+
+Notice: Trying to get property of non-object in %s017.php on line %d
+  child: 
+===DONE===
index cc7153b7ceafc8353a7585e12ce8e48506174509..e5c810944e915189b10130d349c0eb869d6c3bf5 100644 (file)
@@ -28,7 +28,7 @@ $xml1 =<<<EOF
 EOF;
 
 function traverse_xml($pad,$xml) {
-  foreach($xml as $name => $node) {
+  foreach($xml->children() as $name => $node) {
     echo $pad."<$name";
     foreach($node->attributes() as $attr => $value) {
       echo " $attr=\"$value\"";
diff --git a/ext/simplexml/tests/019.phpt b/ext/simplexml/tests/019.phpt
new file mode 100755 (executable)
index 0000000..09f0569
--- /dev/null
@@ -0,0 +1,80 @@
+--TEST--
+SimpleXML and foreach with children()
+--SKIPIF--
+<?php if (!extension_loaded("simplexml")) print "skip"; ?>
+--FILE--
+<?php 
+
+$sxe = simplexml_load_string(<<<EOF
+<?xml version='1.0'?>
+<!DOCTYPE sxe SYSTEM "notfound.dtd">
+<sxe id="elem1">
+ Plain text.
+ <elem1 attr1='first'>
+  Bla bla 1.
+  <!-- comment -->
+  <elem2>
+   Here we have some text data.
+   <elem3>
+    And here some more.
+    <elem4>
+     Wow once again.
+    </elem4>
+   </elem3>
+  </elem2>
+ </elem1>
+ <elem11 attr2='second'>
+  Bla bla 2.
+  <elem111>
+   Foo Bar
+  </elem111>
+ </elem11>
+</sxe>
+EOF
+);
+
+foreach($sxe->children() as $name => $data) {
+       var_dump($name);
+       var_dump(trim($data));
+}
+
+echo "===CLONE===\n";
+
+foreach($sxe->children()->__clone() as $name => $data) {
+       var_dump($name);
+       var_dump(trim($data));
+}
+
+echo "===ELEMENT===\n";
+
+foreach($sxe->elem11->children() as $name => $data) {
+       var_dump($name);
+       var_dump(trim($data));
+}
+
+echo "===COMMENT===\n";
+
+foreach($sxe->elem1->children() as $name => $data) {
+       var_dump($name);
+       var_dump(trim($data));
+}
+
+?>
+===DONE===
+--EXPECT--
+string(5) "elem1"
+string(10) "Bla bla 1."
+string(6) "elem11"
+string(10) "Bla bla 2."
+===CLONE===
+string(5) "elem1"
+string(10) "Bla bla 1."
+string(6) "elem11"
+string(10) "Bla bla 2."
+===ELEMENT===
+string(7) "elem111"
+string(7) "Foo Bar"
+===COMMENT===
+string(5) "elem2"
+string(28) "Here we have some text data."
+===DONE===
diff --git a/ext/simplexml/tests/bug25756.phpt b/ext/simplexml/tests/bug25756.phpt
deleted file mode 100644 (file)
index 843ed40..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
---TEST--
-Bug #25756 (validate_schema_file() broken)
---FILE--
-<?php
-$dir = dirname(__FILE__);
-$valid_schema_file = "$dir/bug25756.xsd";
-$invalid_schema_file = "$dir/bug25756_1.xml";
-$xml_file_valid = "$dir/bug25756_1.xml";
-$xml_file_invalid = "$dir/bug25756_2.xml";
-
-$s = simplexml_load_file($xml_file_valid);
-var_dump($s);
-var_dump($s->validate_schema_file($valid_schema_file));
-var_dump($s->validate_schema_file($invalid_schema_file));
-$s = simplexml_load_file($xml_file_invalid);
-var_dump($s);
-var_dump($s->validate_schema_file($valid_schema_file));
-?>
---EXPECTF--
-object(simplexml_element)#%d (1) {
-  ["items"]=>
-  object(simplexml_element)#%d (1) {
-    ["item"]=>
-    array(2) {
-      [0]=>
-      object(simplexml_element)#%d (2) {
-        ["product-name"]=>
-        string(3) "abc"
-        ["quantity"]=>
-        string(3) "123"
-      }
-      [1]=>
-      object(simplexml_element)#%d (2) {
-        ["product-name"]=>
-        string(3) "def"
-        ["quantity"]=>
-        string(3) "456"
-      }
-    }
-  }
-}
-bool(true)
-
-Warning: simplexml_element::validate_schema_file(): Malformed XML Schema in %sbug25756.php on line %d
-bool(false)
-object(simplexml_element)#%d (1) {
-  ["items"]=>
-  object(simplexml_element)#%d (1) {
-    ["item"]=>
-    array(2) {
-      [0]=>
-      object(simplexml_element)#%d (2) {
-        ["product-name"]=>
-        string(3) "abc"
-        ["quantity"]=>
-        string(3) "abc"
-      }
-      [1]=>
-      object(simplexml_element)#%d (2) {
-        ["product-name"]=>
-        string(3) "abc"
-        ["quantity"]=>
-        string(3) "123"
-      }
-    }
-  }
-}
-
-Warning: Element quantity: failed to validate basic type decimal in %s on line %d
-bool(false)