helly Sat Jan 17 14:41:33 2004 EDT Added files: /php-src/ext/simplexml/tests 019.phpt
Removed files: /php-src/ext/simplexml/tests bug25756.phpt Modified files: /php-src/ext/simplexml CREDITS README php_simplexml.h simplexml.c /php-src/ext/simplexml/tests 006.phpt 007.phpt 008.phpt 011.phpt 012.phpt 014.phpt 014a.phpt 014b.phpt 015.phpt 016.phpt 017.phpt 018.phpt Log: Major bugfix for consistency. # After long discussions we came to a conclusion on how to make this # extension consistent in itself. # Thanks to Rob for all the work
Index: php-src/ext/simplexml/CREDITS diff -u php-src/ext/simplexml/CREDITS:1.3 php-src/ext/simplexml/CREDITS:1.4 --- php-src/ext/simplexml/CREDITS:1.3 Tue Dec 16 15:36:46 2003 +++ php-src/ext/simplexml/CREDITS Sat Jan 17 14:41:31 2004 @@ -1,2 +1,2 @@ simplexml -Sterling Hughes, Marcus Boerger +Sterling Hughes, Marcus Boerger, Rob Richards Index: php-src/ext/simplexml/README diff -u php-src/ext/simplexml/README:1.1 php-src/ext/simplexml/README:1.2 --- php-src/ext/simplexml/README:1.1 Thu Jan 8 16:14:38 2004 +++ php-src/ext/simplexml/README Sat Jan 17 14:41:31 2004 @@ -2,18 +2,23 @@ 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: php-src/ext/simplexml/php_simplexml.h diff -u php-src/ext/simplexml/php_simplexml.h:1.12 php-src/ext/simplexml/php_simplexml.h:1.13 --- php-src/ext/simplexml/php_simplexml.h:1.12 Fri Jan 9 01:12:29 2004 +++ php-src/ext/simplexml/php_simplexml.h Sat Jan 17 14:41:31 2004 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_simplexml.h,v 1.12 2004/01/09 06:12:29 sterling Exp $ */ +/* $Id: php_simplexml.h,v 1.13 2004/01/17 19:41:31 helly Exp $ */ #ifndef PHP_SIMPLEXML_H #define PHP_SIMPLEXML_H @@ -65,14 +65,20 @@ 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: php-src/ext/simplexml/simplexml.c diff -u php-src/ext/simplexml/simplexml.c:1.109 php-src/ext/simplexml/simplexml.c:1.110 --- php-src/ext/simplexml/simplexml.c:1.109 Sat Jan 17 11:36:04 2004 +++ php-src/ext/simplexml/simplexml.c Sat Jan 17 14:41:31 2004 @@ -14,10 +14,11 @@ +----------------------------------------------------------------------+ | Author: Sterling Hughes <[EMAIL PROTECTED]> | | Marcus Boerger <[EMAIL PROTECTED]> | + | Rob Richards <[EMAIL PROTECTED]> | +----------------------------------------------------------------------+ */ -/* $Id: simplexml.c,v 1.109 2004/01/17 16:36:04 helly Exp $ */ +/* $Id: simplexml.c,v 1.110 2004/01/17 19:41:31 helly Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -58,7 +59,7 @@ /* {{{ _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 @@ 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 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 @@ if (!xmlStrcmp(prefix, name)) { return 1; } - } + } return 0; } @@ -127,20 +159,28 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ } GET_NODE(sxe, node); + node = php_sxe_get_first_node(sxe, node TSRMLS_CC); if (node) { node = node->children; @@ -725,9 +722,9 @@ /* }}} */ -/* {{{ xsearch() +/* {{{ xpath() */ -SXE_METHOD(xsearch) +SXE_METHOD(xpath) { php_sxe_object *sxe; zval *value; @@ -801,9 +798,9 @@ * 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 @@ } /* }}} */ -#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 @@ } /* }}} */ -/* {{{ 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 @@ } /* }}} */ -/* {{{ 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(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 @@ { 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ { 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 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 @@ 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} }; @@ -1565,7 +1578,7 @@ { php_info_print_table_start(); php_info_print_table_header(2, "Simplexml support", "enabled"); - php_info_print_table_row(2, "Revision", "$Revision: 1.109 $"); + php_info_print_table_row(2, "Revision", "$Revision: 1.110 $"); php_info_print_table_row(2, "Schema support", #ifdef LIBXML_SCHEMAS_ENABLED "enabled"); Index: php-src/ext/simplexml/tests/006.phpt diff -u php-src/ext/simplexml/tests/006.phpt:1.3 php-src/ext/simplexml/tests/006.phpt:1.4 --- php-src/ext/simplexml/tests/006.phpt:1.3 Sat Jan 17 12:33:10 2004 +++ php-src/ext/simplexml/tests/006.phpt Sat Jan 17 14:41:32 2004 @@ -72,11 +72,9 @@ 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: php-src/ext/simplexml/tests/007.phpt diff -u php-src/ext/simplexml/tests/007.phpt:1.4 php-src/ext/simplexml/tests/007.phpt:1.5 --- php-src/ext/simplexml/tests/007.phpt:1.4 Mon Nov 3 17:42:56 2003 +++ php-src/ext/simplexml/tests/007.phpt Sat Jan 17 14:41:32 2004 @@ -49,11 +49,23 @@ } } ===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: php-src/ext/simplexml/tests/008.phpt diff -u php-src/ext/simplexml/tests/008.phpt:1.1 php-src/ext/simplexml/tests/008.phpt:1.2 --- php-src/ext/simplexml/tests/008.phpt:1.1 Mon Nov 3 17:49:24 2003 +++ php-src/ext/simplexml/tests/008.phpt Sat Jan 17 14:41:32 2004 @@ -5,8 +5,8 @@ --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: php-src/ext/simplexml/tests/011.phpt diff -u php-src/ext/simplexml/tests/011.phpt:1.2 php-src/ext/simplexml/tests/011.phpt:1.3 --- php-src/ext/simplexml/tests/011.phpt:1.2 Tue Dec 16 16:02:54 2003 +++ php-src/ext/simplexml/tests/011.phpt Sat Jan 17 14:41:32 2004 @@ -39,7 +39,7 @@ ===BAR=== bar ===BAZ=== -Array +baz1 ===BAZ0=== baz1 ===BAZ1=== Index: php-src/ext/simplexml/tests/012.phpt diff -u php-src/ext/simplexml/tests/012.phpt:1.2 php-src/ext/simplexml/tests/012.phpt:1.3 --- php-src/ext/simplexml/tests/012.phpt:1.2 Tue Dec 16 16:02:54 2003 +++ php-src/ext/simplexml/tests/012.phpt Sat Jan 17 14:41:32 2004 @@ -18,11 +18,11 @@ $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: php-src/ext/simplexml/tests/014.phpt diff -u php-src/ext/simplexml/tests/014.phpt:1.3 php-src/ext/simplexml/tests/014.phpt:1.4 --- php-src/ext/simplexml/tests/014.phpt:1.3 Sat Jan 10 08:45:10 2004 +++ php-src/ext/simplexml/tests/014.phpt Sat Jan 17 14:41:32 2004 @@ -18,23 +18,40 @@ 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: php-src/ext/simplexml/tests/014a.phpt diff -u php-src/ext/simplexml/tests/014a.phpt:1.1 php-src/ext/simplexml/tests/014a.phpt:1.2 --- php-src/ext/simplexml/tests/014a.phpt:1.1 Sat Jan 10 08:45:10 2004 +++ php-src/ext/simplexml/tests/014a.phpt Sat Jan 17 14:41:32 2004 @@ -18,23 +18,39 @@ 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: php-src/ext/simplexml/tests/014b.phpt diff -u php-src/ext/simplexml/tests/014b.phpt:1.1 php-src/ext/simplexml/tests/014b.phpt:1.2 --- php-src/ext/simplexml/tests/014b.phpt:1.1 Sat Jan 10 08:45:10 2004 +++ php-src/ext/simplexml/tests/014b.phpt Sat Jan 17 14:41:32 2004 @@ -19,23 +19,38 @@ 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: php-src/ext/simplexml/tests/015.phpt diff -u php-src/ext/simplexml/tests/015.phpt:1.2 php-src/ext/simplexml/tests/015.phpt:1.3 --- php-src/ext/simplexml/tests/015.phpt:1.2 Wed Dec 17 10:06:40 2003 +++ php-src/ext/simplexml/tests/015.phpt Sat Jan 17 14:41:32 2004 @@ -34,11 +34,23 @@ $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: php-src/ext/simplexml/tests/016.phpt diff -u php-src/ext/simplexml/tests/016.phpt:1.3 php-src/ext/simplexml/tests/016.phpt:1.4 --- php-src/ext/simplexml/tests/016.phpt:1.3 Mon Dec 22 18:15:34 2003 +++ php-src/ext/simplexml/tests/016.phpt Sat Jan 17 14:41:32 2004 @@ -26,14 +26,32 @@ $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: php-src/ext/simplexml/tests/017.phpt diff -u php-src/ext/simplexml/tests/017.phpt:1.2 php-src/ext/simplexml/tests/017.phpt:1.3 --- php-src/ext/simplexml/tests/017.phpt:1.2 Tue Jan 13 16:28:41 2004 +++ php-src/ext/simplexml/tests/017.phpt Sat Jan 17 14:41:32 2004 @@ -25,52 +25,62 @@ 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: php-src/ext/simplexml/tests/018.phpt diff -u php-src/ext/simplexml/tests/018.phpt:1.1 php-src/ext/simplexml/tests/018.phpt:1.2 --- php-src/ext/simplexml/tests/018.phpt:1.1 Thu Dec 18 08:28:00 2003 +++ php-src/ext/simplexml/tests/018.phpt Sat Jan 17 14:41:32 2004 @@ -28,7 +28,7 @@ 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\""; Index: php-src/ext/simplexml/tests/019.phpt +++ php-src/ext/simplexml/tests/019.phpt --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===
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php