diff options
Diffstat (limited to 'ext/simplexml')
120 files changed, 8001 insertions, 0 deletions
diff --git a/ext/simplexml/CREDITS b/ext/simplexml/CREDITS new file mode 100644 index 0000000..bff168d --- /dev/null +++ b/ext/simplexml/CREDITS @@ -0,0 +1,2 @@ +SimpleXML +Sterling Hughes, Marcus Boerger, Rob Richards diff --git a/ext/simplexml/README b/ext/simplexml/README new file mode 100755 index 0000000..bb9240d --- /dev/null +++ b/ext/simplexml/README @@ -0,0 +1,34 @@ +SimpleXML is meant to be an easy way to access XML data. + +SimpleXML objects follow four basic rules: + +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 properties then the extension always iterates over +all nodes with that element name. Thus method children() must be +called to iterate over subnodes. But also doing the following: +foreach ($obj->node_name as $elem) { + // do something with $elem +} +always results 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. + +Known issues +============ + +Due to engine problems it is currently not possible to access +a subelement by index 0: $object->property[0]. + +TODO +==== + +At the moment property access to multiple elements of the same +name returns an array of SimpleXML objects. This should be an +object of a new type instead so that all kinds of linkage, +assignment and deleting would work. diff --git a/ext/simplexml/config.m4 b/ext/simplexml/config.m4 new file mode 100644 index 0000000..2145e23 --- /dev/null +++ b/ext/simplexml/config.m4 @@ -0,0 +1,27 @@ +dnl $Id$ +dnl config.m4 for extension simplexml + +PHP_ARG_ENABLE(simplexml, whether to enable SimpleXML support, +[ --disable-simplexml Disable SimpleXML support], yes) + +if test -z "$PHP_LIBXML_DIR"; then + PHP_ARG_WITH(libxml-dir, libxml2 install dir, + [ --with-libxml-dir=DIR SimpleXML: libxml2 install prefix], no, no) +fi + +if test "$PHP_SIMPLEXML" != "no"; then + + if test "$PHP_LIBXML" = "no"; then + AC_MSG_ERROR([SimpleXML extension requires LIBXML extension, add --enable-libxml]) + fi + + PHP_SETUP_LIBXML(SIMPLEXML_SHARED_LIBADD, [ + AC_DEFINE(HAVE_SIMPLEXML,1,[ ]) + PHP_NEW_EXTENSION(simplexml, simplexml.c sxe.c, $ext_shared) + PHP_SUBST(SIMPLEXML_SHARED_LIBADD) + ], [ + AC_MSG_ERROR([xml2-config not found. Please check your libxml2 installation.]) + ]) + PHP_ADD_EXTENSION_DEP(simplexml, libxml) + PHP_ADD_EXTENSION_DEP(simplexml, spl, true) +fi diff --git a/ext/simplexml/config.w32 b/ext/simplexml/config.w32 new file mode 100644 index 0000000..2d2ed28 --- /dev/null +++ b/ext/simplexml/config.w32 @@ -0,0 +1,23 @@ +// $Id$ +// vim:ft=javascript + +ARG_WITH("simplexml", "Simple XML support", "yes"); + +if (PHP_SIMPLEXML == "yes") { + if(PHP_LIBXML == "yes" + && ADD_EXTENSION_DEP('simplexml', 'libxml')) { + EXTENSION("simplexml", "simplexml.c sxe.c"); + AC_DEFINE("HAVE_SIMPLEXML", 1, "Simple XML support"); + if (!PHP_SIMPLEXML_SHARED) { + ADD_FLAG("CFLAGS_SIMPLEXML", "/D LIBXML_STATIC"); + } + + if (!ADD_EXTENSION_DEP('simplexml', 'spl', true)) { + MESSAGE("\tSPL support in simplexml disabled"); + } + ADD_FLAG("CFLAGS_SIMPLEXML", "/D PHP_SIMPLEXML_EXPORTS "); + } else { + PHP_SIMPLEXML = "no"; + WARNING("simplexml not enabled; libraries and headers not found"); + } +} diff --git a/ext/simplexml/examples/book.php b/ext/simplexml/examples/book.php new file mode 100644 index 0000000..0416df8 --- /dev/null +++ b/ext/simplexml/examples/book.php @@ -0,0 +1,8 @@ +<?php +$books = simplexml_load_file('book.xml'); +//var_dump($books); +$books = $books->book; +foreach ($books as $book) { + echo "{$book->title} was written by {$book->author}\n"; +} +?> diff --git a/ext/simplexml/examples/book.xml b/ext/simplexml/examples/book.xml new file mode 100644 index 0000000..ea40508 --- /dev/null +++ b/ext/simplexml/examples/book.xml @@ -0,0 +1,10 @@ +<books> + <book> + <title>The Grapes of Wrath</title> + <author>John Steinbeck</author> + </book> + <book> + <title>The Pearl</title> + <author>John Steinbeck</author> + </book> +</books> diff --git a/ext/simplexml/examples/interop.php b/ext/simplexml/examples/interop.php new file mode 100644 index 0000000..9e38ec1 --- /dev/null +++ b/ext/simplexml/examples/interop.php @@ -0,0 +1,27 @@ +<?php +$dom = new domDocument; +$dom->load("book.xml"); +if(!$dom) { + echo "Error while parsing the document\n"; + exit; +} +print "As SimpleXML\n"; + +$s = simplexml_import_dom($dom); +$books = $s->book; +foreach ($books as $book) { + echo "{$book->title} was written by {$book->author}\n"; +} + +print "As DOM \n"; + +$dom = dom_import_simplexml($s); +$books = $dom->getElementsByTagName("book"); +foreach ($books as $book) { + $title = $book->getElementsByTagName("title"); + $author = $book->getElementsByTagName("author"); + echo $title[0]->firstChild->data . " was written by ". $author[0]->firstChild->data . "\n"; +} + + +?> diff --git a/ext/simplexml/examples/security.php b/ext/simplexml/examples/security.php new file mode 100644 index 0000000..17897b3 --- /dev/null +++ b/ext/simplexml/examples/security.php @@ -0,0 +1,6 @@ +<?php +$s = simplexml_load_file('security.xml'); +echo $s->id; +$s->id = 20; +$s->asXML('security.new.xml'); +?> diff --git a/ext/simplexml/examples/security.xml b/ext/simplexml/examples/security.xml new file mode 100644 index 0000000..d954a02 --- /dev/null +++ b/ext/simplexml/examples/security.xml @@ -0,0 +1,4 @@ +<?xml version="1.0"?> +<security> + <id>15</id> +</security> diff --git a/ext/simplexml/examples/xpath.php b/ext/simplexml/examples/xpath.php new file mode 100644 index 0000000..8fcd987 --- /dev/null +++ b/ext/simplexml/examples/xpath.php @@ -0,0 +1,9 @@ +<?php +$books = simplexml_load_file('book.xml'); + +$xpath_result = $books->xpath("/books/book/title"); +foreach($xpath_result as $entry ) { + print "$entry \n"; +} + +?> diff --git a/ext/simplexml/php_simplexml.h b/ext/simplexml/php_simplexml.h new file mode 100644 index 0000000..c340a5e --- /dev/null +++ b/ext/simplexml/php_simplexml.h @@ -0,0 +1,102 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Sterling Hughes <sterling@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifndef PHP_SIMPLEXML_H +#define PHP_SIMPLEXML_H + +extern zend_module_entry simplexml_module_entry; +#define phpext_simplexml_ptr &simplexml_module_entry + +#ifdef ZTS +#include "TSRM.h" +#endif + +#include "ext/libxml/php_libxml.h" +#include <libxml/parser.h> +#include <libxml/parserInternals.h> +#include <libxml/tree.h> +#include <libxml/uri.h> +#include <libxml/xmlerror.h> +#include <libxml/xinclude.h> +#include <libxml/xpath.h> +#include <libxml/xpathInternals.h> +#include <libxml/xpointer.h> +#include <libxml/xmlschemas.h> + +PHP_MINIT_FUNCTION(simplexml); +PHP_MSHUTDOWN_FUNCTION(simplexml); +#ifdef HAVE_SPL +PHP_RINIT_FUNCTION(simplexml); +#endif +PHP_MINFO_FUNCTION(simplexml); + +typedef enum { + SXE_ITER_NONE = 0, + SXE_ITER_ELEMENT = 1, + SXE_ITER_CHILD = 2, + SXE_ITER_ATTRLIST = 3 +} SXE_ITER; + +typedef struct { + zend_object zo; + php_libxml_node_ptr *node; + php_libxml_ref_obj *document; + HashTable *properties; + xmlXPathContextPtr xpath; + struct { + xmlChar *name; + xmlChar *nsprefix; + int isprefix; + SXE_ITER type; + zval *data; + } iter; + zval *tmp; + zend_function *fptr_count; +} php_sxe_object; + +#ifdef ZTS +#define SIMPLEXML_G(v) TSRMG(simplexml_globals_id, zend_simplexml_globals *, v) +#else +#define SIMPLEXML_G(v) (simplexml_globals.v) +#endif + +#ifdef PHP_WIN32 +# ifdef PHP_SIMPLEXML_EXPORTS +# define PHP_SXE_API __declspec(dllexport) +# else +# define PHP_SXE_API __declspec(dllimport) +# endif +#else +# define PHP_SXE_API ZEND_API +#endif + +PHP_SXE_API zend_class_entry *sxe_get_element_class_entry(); + +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * indent-tabs-mode: t + * End: + * vim600: fdm=marker + * vim: noet sw=4 ts=4 + */ diff --git a/ext/simplexml/php_simplexml_exports.h b/ext/simplexml/php_simplexml_exports.h new file mode 100644 index 0000000..66ec3bd --- /dev/null +++ b/ext/simplexml/php_simplexml_exports.h @@ -0,0 +1,67 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Sterling Hughes <sterling@php.net> | + | Marcus Boerger <helly@php.net> | + | Rob Richards <rrichards@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifndef PHP_SIMPLEXML_EXPORTS_H +#define PHP_SIMPLEXML_EXPORTS_H + +#include "php_simplexml.h" + +#define SKIP_TEXT(__p) \ + if ((__p)->type == XML_TEXT_NODE) { \ + goto next_iter; \ + } + +#define GET_NODE(__s, __n) { \ + if ((__s)->node && (__s)->node->node) { \ + __n = (__s)->node->node; \ + } else { \ + __n = NULL; \ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Node no longer exists"); \ + } \ +} + +PHP_SXE_API zend_object_value sxe_object_new(zend_class_entry *ce TSRMLS_DC); +/* {{{ php_sxe_fetch_object() + */ +static inline php_sxe_object * +php_sxe_fetch_object(zval *object TSRMLS_DC) +{ + return (php_sxe_object *) zend_object_store_get_object(object TSRMLS_CC); +} +/* }}} */ + +typedef struct { + zend_object_iterator intern; + php_sxe_object *sxe; +} php_sxe_iterator; + +#endif /* PHP_SIMPLEXML_EXPORTS_H */ + +/** + * Local Variables: + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: t + * End: + * vim600: fdm=marker + * vim: noet sw=4 ts=4 + */ diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c new file mode 100644 index 0000000..59e2a2e --- /dev/null +++ b/ext/simplexml/simplexml.c @@ -0,0 +1,2683 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Sterling Hughes <sterling@php.net> | + | Marcus Boerger <helly@php.net> | + | Rob Richards <rrichards@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id: 692516840b2d7d6e7aedb0bedded1f53b764a99f $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_SIMPLEXML + +#include "php_ini.h" +#include "ext/standard/info.h" +#include "ext/standard/php_string.h" +#include "php_simplexml.h" +#include "php_simplexml_exports.h" +#include "zend_exceptions.h" +#include "zend_interfaces.h" +#include "sxe.h" + +#define SXE_ELEMENT_BY_NAME 0 + +zend_class_entry *sxe_class_entry = NULL; + +PHP_SXE_API zend_class_entry *sxe_get_element_class_entry() /* {{{ */ +{ + return sxe_class_entry; +} +/* }}} */ + +#define SXE_ME(func, arg_info, flags) PHP_ME(simplexml_element, func, arg_info, flags) +#define SXE_MALIAS(func, alias, arg_info, flags) PHP_MALIAS(simplexml_element, func, alias, arg_info, flags) + +#define SXE_METHOD(func) PHP_METHOD(simplexml_element, func) + +static php_sxe_object* php_sxe_object_new(zend_class_entry *ce TSRMLS_DC); +static zend_object_value php_sxe_register_object(php_sxe_object * TSRMLS_DC); +static xmlNodePtr php_sxe_reset_iterator(php_sxe_object *sxe, int use_data TSRMLS_DC); +static xmlNodePtr php_sxe_iterator_fetch(php_sxe_object *sxe, xmlNodePtr node, int use_data TSRMLS_DC); +static zval *sxe_get_value(zval *z TSRMLS_DC); +static void php_sxe_iterator_dtor(zend_object_iterator *iter TSRMLS_DC); +static int php_sxe_iterator_valid(zend_object_iterator *iter TSRMLS_DC); +static void php_sxe_iterator_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC); +static int php_sxe_iterator_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC); +static void php_sxe_iterator_move_forward(zend_object_iterator *iter TSRMLS_DC); +static void php_sxe_iterator_rewind(zend_object_iterator *iter TSRMLS_DC); + +/* {{{ _node_as_zval() + */ +static void _node_as_zval(php_sxe_object *sxe, xmlNodePtr node, zval *value, SXE_ITER itertype, char *name, const xmlChar *nsprefix, int isprefix TSRMLS_DC) +{ + php_sxe_object *subnode; + + subnode = php_sxe_object_new(sxe->zo.ce TSRMLS_CC); + subnode->document = sxe->document; + subnode->document->refcount++; + subnode->iter.type = itertype; + if (name) { + subnode->iter.name = xmlStrdup((xmlChar *)name); + } + if (nsprefix && *nsprefix) { + subnode->iter.nsprefix = xmlStrdup(nsprefix); + subnode->iter.isprefix = isprefix; + } + + php_libxml_increment_node_ptr((php_libxml_node_object *)subnode, node, NULL TSRMLS_CC); + + value->type = IS_OBJECT; + value->value.obj = php_sxe_register_object(subnode TSRMLS_CC); +} +/* }}} */ + +#define APPEND_PREV_ELEMENT(__c, __v) \ + if ((__c) == 1) { \ + array_init(return_value); \ + add_next_index_zval(return_value, __v); \ + } + +#define APPEND_CUR_ELEMENT(__c, __v) \ + if (++(__c) > 1) { \ + add_next_index_zval(return_value, __v); \ + } + +#define GET_NODE(__s, __n) { \ + if ((__s)->node && (__s)->node->node) { \ + __n = (__s)->node->node; \ + } else { \ + __n = NULL; \ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Node no longer exists"); \ + } \ +} + +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, 1 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; + } +} +/* }}} */ + +static inline int match_ns(php_sxe_object *sxe, xmlNodePtr node, xmlChar *name, int prefix) /* {{{ */ +{ + if (name == NULL && (node->ns == NULL || node->ns->prefix == NULL)) { + return 1; + } + + if (node->ns && !xmlStrcmp(prefix ? node->ns->prefix : node->ns->href, name)) { + return 1; + } + + return 0; +} +/* }}} */ + +static xmlNodePtr sxe_get_element_by_offset(php_sxe_object *sxe, long offset, xmlNodePtr node, long *cnt) /* {{{ */ +{ + long nodendx = 0; + + if (sxe->iter.type == SXE_ITER_NONE) { + if (offset == 0) { + if (cnt) { + *cnt = 0; + } + return node; + } else { + return NULL; + } + } + while (node && nodendx <= offset) { + SKIP_TEXT(node) + if (node->type == XML_ELEMENT_NODE && match_ns(sxe, node, sxe->iter.nsprefix, sxe->iter.isprefix)) { + if (sxe->iter.type == SXE_ITER_CHILD || ( + sxe->iter.type == SXE_ITER_ELEMENT && !xmlStrcmp(node->name, sxe->iter.name))) { + if (nodendx == offset) { + break; + } + nodendx++; + } + } +next_iter: + node = node->next; + } + + if (cnt) { + *cnt = nodendx; + } + + return node; +} +/* }}} */ + +static xmlNodePtr sxe_find_element_by_name(php_sxe_object *sxe, xmlNodePtr node, xmlChar *name TSRMLS_DC) /* {{{ */ +{ + while (node) { + SKIP_TEXT(node) + if (node->type == XML_ELEMENT_NODE && match_ns(sxe, node, sxe->iter.nsprefix, sxe->iter.isprefix)) { + if (!xmlStrcmp(node->name, name)) { + return node; + } + } +next_iter: + node = node->next; + } + return NULL; +} /* }}} */ + +static xmlNodePtr sxe_get_element_by_name(php_sxe_object *sxe, xmlNodePtr node, char **name, SXE_ITER *type TSRMLS_DC) /* {{{ */ +{ + int orgtype; + xmlNodePtr orgnode = node; + xmlNodePtr retnode = NULL; + + if (sxe->iter.type != SXE_ITER_ATTRLIST) + { + orgtype = sxe->iter.type; + if (sxe->iter.type == SXE_ITER_NONE) { + sxe->iter.type = SXE_ITER_CHILD; + } + node = php_sxe_get_first_node(sxe, node TSRMLS_CC); + sxe->iter.type = orgtype; + } + + if (sxe->iter.type == SXE_ITER_ELEMENT) { + orgnode = sxe_find_element_by_name(sxe, node, sxe->iter.name TSRMLS_CC); + if (!orgnode) { + return NULL; + } + node = orgnode->children; + } + + while (node) { + SKIP_TEXT(node) + if (node->type == XML_ELEMENT_NODE && match_ns(sxe, node, sxe->iter.nsprefix, sxe->iter.isprefix)) { + if (!xmlStrcmp(node->name, (xmlChar *)*name)) { + if (1||retnode) + { + *type = SXE_ITER_ELEMENT; + return orgnode; + } + retnode = node; + } + } +next_iter: + node = node->next; + } + + if (retnode) + { + *type = SXE_ITER_NONE; + *name = NULL; + return retnode; + } + + return NULL; +} +/* }}} */ + +/* {{{ sxe_prop_dim_read() + */ +static zval * sxe_prop_dim_read(zval *object, zval *member, zend_bool elements, zend_bool attribs, int type TSRMLS_DC) +{ + zval *return_value; + php_sxe_object *sxe; + char *name; + xmlNodePtr node; + xmlAttrPtr attr = NULL; + zval tmp_zv; + int nodendx = 0; + int test = 0; + + sxe = php_sxe_fetch_object(object TSRMLS_CC); + + if (!member || Z_TYPE_P(member) == IS_LONG) { + if (sxe->iter.type != SXE_ITER_ATTRLIST) { + attribs = 0; + elements = 1; + } else if (!member) { + /* This happens when the user did: $sxe[]->foo = $value */ + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Cannot create unnamed attribute"); + return NULL; + } + name = NULL; + } else { + if (Z_TYPE_P(member) != IS_STRING) { + tmp_zv = *member; + zval_copy_ctor(&tmp_zv); + member = &tmp_zv; + convert_to_string(member); + } + name = Z_STRVAL_P(member); + } + + GET_NODE(sxe, node); + + if (sxe->iter.type == SXE_ITER_ATTRLIST) { + attribs = 1; + elements = 0; + node = php_sxe_get_first_node(sxe, node TSRMLS_CC); + attr = (xmlAttrPtr)node; + test = sxe->iter.name != NULL; + } else if (sxe->iter.type != SXE_ITER_CHILD) { + node = php_sxe_get_first_node(sxe, node TSRMLS_CC); + attr = node ? node->properties : NULL; + test = 0; + if (!member && node && node->parent && + node->parent->type == XML_DOCUMENT_NODE) { + /* This happens when the user did: $sxe[]->foo = $value */ + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Cannot create unnamed attribute"); + return NULL; + } + } + + MAKE_STD_ZVAL(return_value); + ZVAL_NULL(return_value); + + if (node) { + if (attribs) { + if (Z_TYPE_P(member) != IS_LONG || sxe->iter.type == SXE_ITER_ATTRLIST) { + if (Z_TYPE_P(member) == IS_LONG) { + while (attr && nodendx <= Z_LVAL_P(member)) { + if ((!test || !xmlStrcmp(attr->name, sxe->iter.name)) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { + if (nodendx == Z_LVAL_P(member)) { + _node_as_zval(sxe, (xmlNodePtr) attr, return_value, SXE_ITER_NONE, NULL, sxe->iter.nsprefix, sxe->iter.isprefix TSRMLS_CC); + break; + } + nodendx++; + } + attr = attr->next; + } + } else { + while (attr) { + if ((!test || !xmlStrcmp(attr->name, sxe->iter.name)) && !xmlStrcmp(attr->name, (xmlChar *)name) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { + _node_as_zval(sxe, (xmlNodePtr) attr, return_value, SXE_ITER_NONE, NULL, sxe->iter.nsprefix, sxe->iter.isprefix TSRMLS_CC); + break; + } + attr = attr->next; + } + } + } + } + + if (elements) { + if (!sxe->node) { + php_libxml_increment_node_ptr((php_libxml_node_object *)sxe, node, NULL TSRMLS_CC); + } + if (!member || Z_TYPE_P(member) == IS_LONG) { + long cnt = 0; + xmlNodePtr mynode = node; + + if (sxe->iter.type == SXE_ITER_CHILD) { + node = php_sxe_get_first_node(sxe, node TSRMLS_CC); + } + if (sxe->iter.type == SXE_ITER_NONE) { + if (member && Z_LVAL_P(member) > 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot add element %s number %ld when only 0 such elements exist", mynode->name, Z_LVAL_P(member)); + } + } else if (member) { + node = sxe_get_element_by_offset(sxe, Z_LVAL_P(member), node, &cnt); + } else { + node = NULL; + } + if (node) { + _node_as_zval(sxe, node, return_value, SXE_ITER_NONE, NULL, sxe->iter.nsprefix, sxe->iter.isprefix TSRMLS_CC); + } else if (type == BP_VAR_W || type == BP_VAR_RW) { + if (member && cnt < Z_LVAL_P(member)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot add element %s number %ld when only %ld such elements exist", mynode->name, Z_LVAL_P(member), cnt); + } + node = xmlNewTextChild(mynode->parent, mynode->ns, mynode->name, NULL); + _node_as_zval(sxe, node, return_value, SXE_ITER_NONE, NULL, sxe->iter.nsprefix, sxe->iter.isprefix TSRMLS_CC); + } + } else { +#if SXE_ELEMENT_BY_NAME + int newtype; + + GET_NODE(sxe, node); + node = sxe_get_element_by_name(sxe, node, &name, &newtype TSRMLS_CC); + if (node) { + _node_as_zval(sxe, node, return_value, newtype, name, sxe->iter.nsprefix, sxe->iter.isprefix TSRMLS_CC); + } +#else + _node_as_zval(sxe, node, return_value, SXE_ITER_ELEMENT, name, sxe->iter.nsprefix, sxe->iter.isprefix TSRMLS_CC); +#endif + } + } + } + + Z_SET_REFCOUNT_P(return_value, 0); + Z_UNSET_ISREF_P(return_value); + + if (member == &tmp_zv) { + zval_dtor(&tmp_zv); + } + if (Z_TYPE_P(return_value) == IS_NULL) { + FREE_ZVAL(return_value); + return_value = &EG(uninitialized_zval); + } + + return return_value; +} +/* }}} */ + +/* {{{ sxe_property_read() + */ +static zval * sxe_property_read(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) +{ + return sxe_prop_dim_read(object, member, 1, 0, type TSRMLS_CC); +} +/* }}} */ + +/* {{{ sxe_dimension_read() + */ +static zval * sxe_dimension_read(zval *object, zval *offset, int type TSRMLS_DC) +{ + return sxe_prop_dim_read(object, offset, 0, 1, type TSRMLS_CC); +} +/* }}} */ + +/* {{{ change_node_zval() + */ +static void change_node_zval(xmlNodePtr node, zval *value TSRMLS_DC) +{ + zval value_copy; + xmlChar *buffer; + int buffer_len; + + if (!value) + { + xmlNodeSetContentLen(node, (xmlChar *)"", 0); + return; + } + switch (Z_TYPE_P(value)) { + case IS_LONG: + case IS_BOOL: + case IS_DOUBLE: + case IS_NULL: + if (Z_REFCOUNT_P(value) > 1) { + value_copy = *value; + zval_copy_ctor(&value_copy); + value = &value_copy; + } + convert_to_string(value); + /* break missing intentionally */ + case IS_STRING: + buffer = xmlEncodeEntitiesReentrant(node->doc, (xmlChar *)Z_STRVAL_P(value)); + buffer_len = xmlStrlen(buffer); + /* check for NULL buffer in case of memory error in xmlEncodeEntitiesReentrant */ + if (buffer) { + xmlNodeSetContentLen(node, buffer, buffer_len); + xmlFree(buffer); + } + if (value == &value_copy) { + zval_dtor(value); + } + break; + default: + php_error_docref(NULL TSRMLS_CC, E_WARNING, "It is not possible to assign complex types to nodes"); + break; + } +} +/* }}} */ + +/* {{{ sxe_property_write() + */ +static int sxe_prop_dim_write(zval *object, zval *member, zval *value, zend_bool elements, zend_bool attribs, xmlNodePtr *pnewnode TSRMLS_DC) +{ + php_sxe_object *sxe; + xmlNodePtr node; + xmlNodePtr newnode = NULL; + xmlNodePtr mynode; + xmlNodePtr tempnode; + xmlAttrPtr attr = NULL; + int counter = 0; + int is_attr = 0; + int nodendx = 0; + int test = 0; + int new_value = 0; + long cnt = 0; + int retval = SUCCESS; + zval tmp_zv, trim_zv, value_copy; + + sxe = php_sxe_fetch_object(object TSRMLS_CC); + + if (!member || Z_TYPE_P(member) == IS_LONG) { + if (sxe->iter.type != SXE_ITER_ATTRLIST) { + attribs = 0; + elements = 1; + } else if (!member) { + /* This happens when the user did: $sxe[] = $value + * and could also be E_PARSE, but we use this only during parsing + * and this is during runtime. + */ + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Cannot create unnamed attribute"); + return FAILURE; + } + } 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"); + if (member == &tmp_zv) { + zval_dtor(&tmp_zv); + } + return FAILURE; + } + } + + GET_NODE(sxe, node); + + if (sxe->iter.type == SXE_ITER_ATTRLIST) { + attribs = 1; + elements = 0; + node = php_sxe_get_first_node(sxe, node TSRMLS_CC); + attr = (xmlAttrPtr)node; + test = sxe->iter.name != NULL; + } else if (sxe->iter.type != SXE_ITER_CHILD) { + mynode = node; + node = php_sxe_get_first_node(sxe, node TSRMLS_CC); + attr = node ? node->properties : NULL; + test = 0; + if (!member && node && node->parent && + node->parent->type == XML_DOCUMENT_NODE) { + /* This happens when the user did: $sxe[] = $value + * and could also be E_PARSE, but we use this only during parsing + * and this is during runtime. + */ + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Cannot create unnamed attribute"); + return FAILURE; + } + if (attribs && !node && sxe->iter.type == SXE_ITER_ELEMENT) { + node = xmlNewChild(mynode, mynode->ns, sxe->iter.name, NULL); + attr = node->properties; + } + } + + mynode = node; + + if (value) { + switch (Z_TYPE_P(value)) { + case IS_LONG: + case IS_BOOL: + case IS_DOUBLE: + case IS_NULL: + if (Z_REFCOUNT_P(value) > 1) { + value_copy = *value; + zval_copy_ctor(&value_copy); + value = &value_copy; + } + convert_to_string(value); + break; + case IS_STRING: + break; + case IS_OBJECT: + if (Z_OBJCE_P(value) == sxe_class_entry) { + value = sxe_get_value(value TSRMLS_CC); + INIT_PZVAL(value); + new_value = 1; + break; + } + /* break is missing intentionally */ + default: + if (member == &tmp_zv) { + zval_dtor(&tmp_zv); + } + zend_error(E_WARNING, "It is not yet possible to assign complex types to %s", attribs ? "attributes" : "properties"); + return FAILURE; + } + } + + if (node) { + if (attribs) { + if (Z_TYPE_P(member) == IS_LONG) { + while (attr && nodendx <= Z_LVAL_P(member)) { + if ((!test || !xmlStrcmp(attr->name, sxe->iter.name)) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { + if (nodendx == Z_LVAL_P(member)) { + is_attr = 1; + ++counter; + break; + } + nodendx++; + } + attr = attr->next; + } + } else { + while (attr) { + if ((!test || !xmlStrcmp(attr->name, sxe->iter.name)) && !xmlStrcmp(attr->name, (xmlChar *)Z_STRVAL_P(member)) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { + is_attr = 1; + ++counter; + break; + } + attr = attr->next; + } + } + + } + + if (elements) { + if (!member || Z_TYPE_P(member) == IS_LONG) { + if (node->type == XML_ATTRIBUTE_NODE) { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Cannot create duplicate attribute"); + return FAILURE; + } + + if (sxe->iter.type == SXE_ITER_NONE) { + newnode = node; + ++counter; + if (member && Z_LVAL_P(member) > 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot add element %s number %ld when only 0 such elements exist", mynode->name, Z_LVAL_P(member)); + retval = FAILURE; + } + } else if (member) { + newnode = sxe_get_element_by_offset(sxe, Z_LVAL_P(member), node, &cnt); + if (newnode) { + ++counter; + } + } + } else { + node = node->children; + while (node) { + SKIP_TEXT(node); + + if (!xmlStrcmp(node->name, (xmlChar *)Z_STRVAL_P(member))) { + newnode = node; + ++counter; + } + +next_iter: + node = node->next; + } + } + } + + if (counter == 1) { + if (is_attr) { + newnode = (xmlNodePtr) attr; + } + if (value) { + while ((tempnode = (xmlNodePtr) newnode->children)) { + xmlUnlinkNode(tempnode); + php_libxml_node_free_resource((xmlNodePtr) tempnode TSRMLS_CC); + } + change_node_zval(newnode, value TSRMLS_CC); + } + } else if (counter > 1) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot assign to an array of nodes (duplicate subnodes or attr detected)"); + retval = FAILURE; + } else if (elements) { + if (!node) { + if (!member || Z_TYPE_P(member) == IS_LONG) { + newnode = xmlNewTextChild(mynode->parent, mynode->ns, mynode->name, value ? (xmlChar *)Z_STRVAL_P(value) : NULL); + } else { + newnode = xmlNewTextChild(mynode, mynode->ns, (xmlChar *)Z_STRVAL_P(member), value ? (xmlChar *)Z_STRVAL_P(value) : NULL); + } + } else if (!member || Z_TYPE_P(member) == IS_LONG) { + if (member && cnt < Z_LVAL_P(member)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot add element %s number %ld when only %ld such elements exist", mynode->name, Z_LVAL_P(member), cnt); + retval = FAILURE; + } + newnode = xmlNewTextChild(mynode->parent, mynode->ns, mynode->name, value ? (xmlChar *)Z_STRVAL_P(value) : NULL); + } + } else if (attribs) { + if (Z_TYPE_P(member) == IS_LONG) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot change attribute number %ld when only %d attributes exist", Z_LVAL_P(member), nodendx); + retval = FAILURE; + } else { + newnode = (xmlNodePtr)xmlNewProp(node, (xmlChar *)Z_STRVAL_P(member), value ? (xmlChar *)Z_STRVAL_P(value) : NULL); + } + } + } + + if (member == &tmp_zv) { + zval_dtor(&tmp_zv); + } + if (pnewnode) { + *pnewnode = newnode; + } + if (value && value == &value_copy) { + zval_dtor(value); + } + if (new_value) { + zval_ptr_dtor(&value); + } + return retval; +} +/* }}} */ + +/* {{{ sxe_property_write() + */ +static void sxe_property_write(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC) +{ + sxe_prop_dim_write(object, member, value, 1, 0, NULL TSRMLS_CC); +} +/* }}} */ + +/* {{{ sxe_dimension_write() + */ +static void sxe_dimension_write(zval *object, zval *offset, zval *value TSRMLS_DC) +{ + sxe_prop_dim_write(object, offset, value, 0, 1, NULL TSRMLS_CC); +} +/* }}} */ + +static zval** sxe_property_get_adr(zval *object, zval *member, const zend_literal *key TSRMLS_DC) /* {{{ */ +{ + php_sxe_object *sxe; + xmlNodePtr node; + zval *return_value; + char *name; + SXE_ITER type; + + sxe = php_sxe_fetch_object(object TSRMLS_CC); + + GET_NODE(sxe, node); + convert_to_string(member); + name = Z_STRVAL_P(member); + node = sxe_get_element_by_name(sxe, node, &name, &type TSRMLS_CC); + if (node) { + return NULL; + } + if (sxe_prop_dim_write(object, member, NULL, 1, 0, &node TSRMLS_CC) != SUCCESS) { + return NULL; + } + type = SXE_ITER_NONE; + name = NULL; + + MAKE_STD_ZVAL(return_value); + _node_as_zval(sxe, node, return_value, type, name, sxe->iter.nsprefix, sxe->iter.isprefix TSRMLS_CC); + + sxe = php_sxe_fetch_object(return_value TSRMLS_CC); + if (sxe->tmp) { + zval_ptr_dtor(&sxe->tmp); + } + sxe->tmp = return_value; + Z_SET_ISREF_P(return_value); + + return &sxe->tmp; +} +/* }}} */ + +/* {{{ sxe_prop_dim_exists() + */ +static int sxe_prop_dim_exists(zval *object, zval *member, int check_empty, zend_bool elements, zend_bool attribs TSRMLS_DC) +{ + php_sxe_object *sxe; + xmlNodePtr node; + xmlAttrPtr attr = NULL; + int exists = 0; + int test = 0; + zval tmp_zv; + + if (Z_TYPE_P(member) != IS_STRING && Z_TYPE_P(member) != IS_LONG) { + tmp_zv = *member; + zval_copy_ctor(&tmp_zv); + member = &tmp_zv; + convert_to_string(member); + } + + sxe = php_sxe_fetch_object(object TSRMLS_CC); + + GET_NODE(sxe, node); + + if (Z_TYPE_P(member) == IS_LONG) { + if (sxe->iter.type != SXE_ITER_ATTRLIST) { + attribs = 0; + elements = 1; + if (sxe->iter.type == SXE_ITER_CHILD) { + node = php_sxe_get_first_node(sxe, node TSRMLS_CC); + } + } + } + + if (sxe->iter.type == SXE_ITER_ATTRLIST) { + attribs = 1; + elements = 0; + node = php_sxe_get_first_node(sxe, node TSRMLS_CC); + attr = (xmlAttrPtr)node; + test = sxe->iter.name != NULL; + } else if (sxe->iter.type != SXE_ITER_CHILD) { + node = php_sxe_get_first_node(sxe, node TSRMLS_CC); + attr = node ? node->properties : NULL; + test = 0; + } + + if (node) { + if (attribs) { + if (Z_TYPE_P(member) == IS_LONG) { + int nodendx = 0; + + while (attr && nodendx <= Z_LVAL_P(member)) { + if ((!test || !xmlStrcmp(attr->name, sxe->iter.name)) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { + if (nodendx == Z_LVAL_P(member)) { + exists = 1; + break; + } + nodendx++; + } + attr = attr->next; + } + } else { + while (attr) { + if ((!test || !xmlStrcmp(attr->name, sxe->iter.name)) && !xmlStrcmp(attr->name, (xmlChar *)Z_STRVAL_P(member)) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { + exists = 1; + break; + } + + attr = attr->next; + } + } + if (exists && check_empty == 1 && + (!attr->children || !attr->children->content || !attr->children->content[0] || !xmlStrcmp(attr->children->content, "0")) ) { + /* Attribute with no content in it's text node */ + exists = 0; + } + } + + if (elements) { + if (Z_TYPE_P(member) == IS_LONG) { + if (sxe->iter.type == SXE_ITER_CHILD) { + node = php_sxe_get_first_node(sxe, node TSRMLS_CC); + } + node = sxe_get_element_by_offset(sxe, Z_LVAL_P(member), node, NULL); + } + else { + node = node->children; + while (node) { + xmlNodePtr nnext; + nnext = node->next; + if ((node->type == XML_ELEMENT_NODE) && !xmlStrcmp(node->name, (xmlChar *)Z_STRVAL_P(member))) { + break; + } + node = nnext; + } + } + if (node) { + exists = 1; + if (check_empty == 1 && + (!node->children || (node->children->type == XML_TEXT_NODE && !node->children->next && + (!node->children->content || !node->children->content[0] || !xmlStrcmp(node->children->content, "0")))) ) { + exists = 0; + } + } + } + } + + if (member == &tmp_zv) { + zval_dtor(&tmp_zv); + } + + return exists; +} +/* }}} */ + +/* {{{ sxe_property_exists() + */ +static int sxe_property_exists(zval *object, zval *member, int check_empty, const zend_literal *key TSRMLS_DC) +{ + return sxe_prop_dim_exists(object, member, check_empty, 1, 0 TSRMLS_CC); +} +/* }}} */ + +/* {{{ sxe_property_exists() + */ +static int sxe_dimension_exists(zval *object, zval *member, int check_empty TSRMLS_DC) +{ + return sxe_prop_dim_exists(object, member, check_empty, 0, 1 TSRMLS_CC); +} +/* }}} */ + +/* {{{ sxe_prop_dim_delete() + */ +static void sxe_prop_dim_delete(zval *object, zval *member, zend_bool elements, zend_bool attribs TSRMLS_DC) +{ + php_sxe_object *sxe; + xmlNodePtr node; + xmlNodePtr nnext; + xmlAttrPtr attr = NULL; + xmlAttrPtr anext; + zval tmp_zv; + int test = 0; + + if (Z_TYPE_P(member) != IS_STRING && Z_TYPE_P(member) != IS_LONG) { + tmp_zv = *member; + zval_copy_ctor(&tmp_zv); + member = &tmp_zv; + convert_to_string(member); + } + + sxe = php_sxe_fetch_object(object TSRMLS_CC); + + GET_NODE(sxe, node); + + if (Z_TYPE_P(member) == IS_LONG) { + if (sxe->iter.type != SXE_ITER_ATTRLIST) { + attribs = 0; + elements = 1; + if (sxe->iter.type == SXE_ITER_CHILD) { + node = php_sxe_get_first_node(sxe, node TSRMLS_CC); + } + } + } + + if (sxe->iter.type == SXE_ITER_ATTRLIST) { + attribs = 1; + elements = 0; + node = php_sxe_get_first_node(sxe, node TSRMLS_CC); + attr = (xmlAttrPtr)node; + test = sxe->iter.name != NULL; + } else if (sxe->iter.type != SXE_ITER_CHILD) { + node = php_sxe_get_first_node(sxe, node TSRMLS_CC); + attr = node ? node->properties : NULL; + test = 0; + } + + if (node) { + if (attribs) { + if (Z_TYPE_P(member) == IS_LONG) { + int nodendx = 0; + + while (attr && nodendx <= Z_LVAL_P(member)) { + if ((!test || !xmlStrcmp(attr->name, sxe->iter.name)) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { + if (nodendx == Z_LVAL_P(member)) { + xmlUnlinkNode((xmlNodePtr) attr); + php_libxml_node_free_resource((xmlNodePtr) attr TSRMLS_CC); + break; + } + nodendx++; + } + attr = attr->next; + } + } else { + while (attr) { + anext = attr->next; + if ((!test || !xmlStrcmp(attr->name, sxe->iter.name)) && !xmlStrcmp(attr->name, (xmlChar *)Z_STRVAL_P(member)) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { + xmlUnlinkNode((xmlNodePtr) attr); + php_libxml_node_free_resource((xmlNodePtr) attr TSRMLS_CC); + break; + } + attr = anext; + } + } + } + + if (elements) { + if (Z_TYPE_P(member) == IS_LONG) { + if (sxe->iter.type == SXE_ITER_CHILD) { + node = php_sxe_get_first_node(sxe, node TSRMLS_CC); + } + node = sxe_get_element_by_offset(sxe, Z_LVAL_P(member), node, NULL); + if (node) { + xmlUnlinkNode(node); + php_libxml_node_free_resource(node TSRMLS_CC); + } + } else { + node = node->children; + while (node) { + nnext = node->next; + + SKIP_TEXT(node); + + if (!xmlStrcmp(node->name, (xmlChar *)Z_STRVAL_P(member))) { + xmlUnlinkNode(node); + php_libxml_node_free_resource(node TSRMLS_CC); + } + +next_iter: + node = nnext; + } + } + } + } + + if (member == &tmp_zv) { + zval_dtor(&tmp_zv); + } +} +/* }}} */ + +/* {{{ sxe_property_delete() + */ +static void sxe_property_delete(zval *object, zval *member, const zend_literal *key TSRMLS_DC) +{ + sxe_prop_dim_delete(object, member, 1, 0 TSRMLS_CC); +} +/* }}} */ + +/* {{{ sxe_dimension_unset() + */ +static void sxe_dimension_delete(zval *object, zval *offset TSRMLS_DC) +{ + sxe_prop_dim_delete(object, offset, 0, 1 TSRMLS_CC); +} +/* }}} */ + +static inline char * sxe_xmlNodeListGetString(xmlDocPtr doc, xmlNodePtr list, int inLine) /* {{{ */ +{ + xmlChar *tmp = xmlNodeListGetString(doc, list, inLine); + char *res; + + if (tmp) { + res = estrdup((char*)tmp); + xmlFree(tmp); + } else { + res = STR_EMPTY_ALLOC(); + } + + return res; +} +/* }}} */ + +/* {{{ _get_base_node_value() + */ +static void _get_base_node_value(php_sxe_object *sxe_ref, xmlNodePtr node, zval **value, xmlChar *nsprefix, int isprefix TSRMLS_DC) +{ + php_sxe_object *subnode; + xmlChar *contents; + + MAKE_STD_ZVAL(*value); + + if (node->children && node->children->type == XML_TEXT_NODE && !xmlIsBlankNode(node->children)) { + contents = xmlNodeListGetString(node->doc, node->children, 1); + if (contents) { + ZVAL_STRING(*value, (char *)contents, 1); + xmlFree(contents); + } + } else { + subnode = php_sxe_object_new(sxe_ref->zo.ce TSRMLS_CC); + subnode->document = sxe_ref->document; + subnode->document->refcount++; + if (nsprefix && *nsprefix) { + subnode->iter.nsprefix = xmlStrdup((xmlChar *)nsprefix); + subnode->iter.isprefix = isprefix; + } + php_libxml_increment_node_ptr((php_libxml_node_object *)subnode, node, NULL TSRMLS_CC); + + (*value)->type = IS_OBJECT; + (*value)->value.obj = php_sxe_register_object(subnode TSRMLS_CC); + /*zval_add_ref(value);*/ + } +} +/* }}} */ + +static void sxe_properties_add(HashTable *rv, char *name, int namelen, zval *value TSRMLS_DC) /* {{{ */ +{ + zval **data_ptr; + zval *newptr; + ulong h = zend_hash_func(name, namelen); + + if (zend_hash_quick_find(rv, name, namelen, h, (void **) &data_ptr) == SUCCESS) { + if (Z_TYPE_PP(data_ptr) == IS_ARRAY) { + zend_hash_next_index_insert(Z_ARRVAL_PP(data_ptr), &value, sizeof(zval *), NULL); + } else { + MAKE_STD_ZVAL(newptr); + array_init(newptr); + + zval_add_ref(data_ptr); + zend_hash_next_index_insert(Z_ARRVAL_P(newptr), data_ptr, sizeof(zval *), NULL); + zend_hash_next_index_insert(Z_ARRVAL_P(newptr), &value, sizeof(zval *), NULL); + + zend_hash_quick_update(rv, name, namelen, h, &newptr, sizeof(zval *), NULL); + } + } else { + zend_hash_quick_update(rv, name, namelen, h, &value, sizeof(zval *), NULL); + } +} +/* }}} */ + +static HashTable * sxe_get_prop_hash(zval *object, int is_debug TSRMLS_DC) /* {{{ */ +{ + zval *value; + zval *zattr; + HashTable *rv; + php_sxe_object *sxe; + char *name; + xmlNodePtr node; + xmlAttrPtr attr; + int namelen; + int test; + char use_iter; + zval *iter_data; + + use_iter = 0; + + sxe = php_sxe_fetch_object(object TSRMLS_CC); + + if (is_debug) { + ALLOC_HASHTABLE(rv); + zend_hash_init(rv, 0, NULL, ZVAL_PTR_DTOR, 0); + } + else if (sxe->properties) { + zend_hash_clean(sxe->properties); + rv = sxe->properties; + } else { + ALLOC_HASHTABLE(rv); + zend_hash_init(rv, 0, NULL, ZVAL_PTR_DTOR, 0); + sxe->properties = rv; + } + + GET_NODE(sxe, node); + if (!node) { + return rv; + } + if (is_debug || sxe->iter.type != SXE_ITER_CHILD) { + if (sxe->iter.type == SXE_ITER_ELEMENT) { + node = php_sxe_get_first_node(sxe, node TSRMLS_CC); + } + if (!node || node->type != XML_ENTITY_DECL) { + attr = node ? (xmlAttrPtr)node->properties : NULL; + zattr = NULL; + test = sxe->iter.name && sxe->iter.type == SXE_ITER_ATTRLIST; + while (attr) { + if ((!test || !xmlStrcmp(attr->name, sxe->iter.name)) && match_ns(sxe, (xmlNodePtr)attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { + MAKE_STD_ZVAL(value); + ZVAL_STRING(value, sxe_xmlNodeListGetString((xmlDocPtr) sxe->document->ptr, attr->children, 1), 0); + namelen = xmlStrlen(attr->name) + 1; + if (!zattr) { + MAKE_STD_ZVAL(zattr); + array_init(zattr); + sxe_properties_add(rv, "@attributes", sizeof("@attributes"), zattr TSRMLS_CC); + } + add_assoc_zval_ex(zattr, (char*)attr->name, namelen, value); + } + attr = attr->next; + } + } + } + + GET_NODE(sxe, node); + node = php_sxe_get_first_node(sxe, node TSRMLS_CC); + + if (node && sxe->iter.type != SXE_ITER_ATTRLIST) { + if (node->type == XML_ATTRIBUTE_NODE) { + MAKE_STD_ZVAL(value); + ZVAL_STRING(value, sxe_xmlNodeListGetString(node->doc, node->children, 1), 0); + zend_hash_next_index_insert(rv, &value, sizeof(zval *), NULL); + node = NULL; + } else if (sxe->iter.type != SXE_ITER_CHILD) { + + if ( !node->children || !node->parent || node->children->next || node->children->children || node->parent->children == node->parent->last ) { + node = node->children; + } else { + iter_data = sxe->iter.data; + sxe->iter.data = NULL; + + node = php_sxe_reset_iterator(sxe, 0 TSRMLS_CC); + + use_iter = 1; + } + } + + while (node) { + if (node->children != NULL || node->prev != NULL || node->next != NULL) { + SKIP_TEXT(node); + } else { + if (node->type == XML_TEXT_NODE) { + const xmlChar *cur = node->content; + + if (*cur != 0) { + MAKE_STD_ZVAL(value); + ZVAL_STRING(value, sxe_xmlNodeListGetString(node->doc, node, 1), 0); + zend_hash_next_index_insert(rv, &value, sizeof(zval *), NULL); + } + goto next_iter; + } + } + + if (node->type == XML_ELEMENT_NODE && (! match_ns(sxe, node, sxe->iter.nsprefix, sxe->iter.isprefix))) { + goto next_iter; + } + + name = (char *) node->name; + if (!name) { + goto next_iter; + } else { + namelen = xmlStrlen(node->name) + 1; + } + + _get_base_node_value(sxe, node, &value, sxe->iter.nsprefix, sxe->iter.isprefix TSRMLS_CC); + + if ( use_iter ) { + zend_hash_next_index_insert(rv, &value, sizeof(zval *), NULL); + } else { + sxe_properties_add(rv, name, namelen, value TSRMLS_CC); + } +next_iter: + if ( use_iter ) { + node = php_sxe_iterator_fetch(sxe, node->next, 0 TSRMLS_CC); + } else { + node = node->next; + } + } + } + + if ( use_iter ) { + if (sxe->iter.data) { + zval_ptr_dtor(&sxe->iter.data); + } + sxe->iter.data = iter_data; + } + + return rv; +} +/* }}} */ + +static HashTable * sxe_get_gc(zval *object, zval ***table, int *n TSRMLS_DC) /* {{{ */ { + php_sxe_object *sxe; + sxe = php_sxe_fetch_object(object TSRMLS_CC); + + *table = NULL; + *n = 0; + return sxe->properties; +} +/* }}} */ + +static HashTable * sxe_get_properties(zval *object TSRMLS_DC) /* {{{ */ +{ + return sxe_get_prop_hash(object, 0 TSRMLS_CC); +} +/* }}} */ + +static HashTable * sxe_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */ +{ + *is_temp = 1; + return sxe_get_prop_hash(object, 1 TSRMLS_CC); +} +/* }}} */ + +static int sxe_objects_compare(zval *object1, zval *object2 TSRMLS_DC) /* {{{ */ +{ + php_sxe_object *sxe1; + php_sxe_object *sxe2; + + sxe1 = php_sxe_fetch_object(object1 TSRMLS_CC); + sxe2 = php_sxe_fetch_object(object2 TSRMLS_CC); + + if (sxe1->node == NULL) { + if (sxe2->node) { + return 1; + } else if (sxe1->document->ptr == sxe2->document->ptr) { + return 0; + } + } else { + return !(sxe1->node == sxe2->node); + } + return 1; +} +/* }}} */ + +/* {{{ proto array SimpleXMLElement::xpath(string path) + Runs XPath query on the XML data */ +SXE_METHOD(xpath) +{ + php_sxe_object *sxe; + zval *value; + char *query; + int query_len; + int i; + int nsnbr = 0; + xmlNsPtr *ns = NULL; + xmlXPathObjectPtr retval; + xmlNodeSetPtr result; + xmlNodePtr nodeptr; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &query, &query_len) == FAILURE) { + return; + } + + sxe = php_sxe_fetch_object(getThis() TSRMLS_CC); + + if (sxe->iter.type == SXE_ITER_ATTRLIST) { + return; /* attributes don't have attributes */ + } + + if (!sxe->xpath) { + sxe->xpath = xmlXPathNewContext((xmlDocPtr) sxe->document->ptr); + } + if (!sxe->node) { + php_libxml_increment_node_ptr((php_libxml_node_object *)sxe, xmlDocGetRootElement((xmlDocPtr) sxe->document->ptr), NULL TSRMLS_CC); + } + + nodeptr = php_sxe_get_first_node(sxe, sxe->node->node TSRMLS_CC); + + sxe->xpath->node = nodeptr; + + ns = xmlGetNsList((xmlDocPtr) sxe->document->ptr, nodeptr); + if (ns != NULL) { + while (ns[nsnbr] != NULL) { + nsnbr++; + } + } + + sxe->xpath->namespaces = ns; + sxe->xpath->nsNr = nsnbr; + + retval = xmlXPathEval((xmlChar *)query, sxe->xpath); + if (ns != NULL) { + xmlFree(ns); + sxe->xpath->namespaces = NULL; + sxe->xpath->nsNr = 0; + } + + if (!retval) { + RETURN_FALSE; + } + + result = retval->nodesetval; + + array_init(return_value); + + if (result != NULL) { + for (i = 0; i < result->nodeNr; ++i) { + nodeptr = result->nodeTab[i]; + if (nodeptr->type == XML_TEXT_NODE || nodeptr->type == XML_ELEMENT_NODE || nodeptr->type == XML_ATTRIBUTE_NODE) { + MAKE_STD_ZVAL(value); + /** + * Detect the case where the last selector is text(), simplexml + * always accesses the text() child by default, therefore we assign + * to the parent node. + */ + if (nodeptr->type == XML_TEXT_NODE) { + _node_as_zval(sxe, nodeptr->parent, value, SXE_ITER_NONE, NULL, NULL, 0 TSRMLS_CC); + } else if (nodeptr->type == XML_ATTRIBUTE_NODE) { + _node_as_zval(sxe, nodeptr->parent, value, SXE_ITER_ATTRLIST, (char*)nodeptr->name, nodeptr->ns ? (xmlChar *)nodeptr->ns->href : NULL, 0 TSRMLS_CC); + } else { + _node_as_zval(sxe, nodeptr, value, SXE_ITER_NONE, NULL, NULL, 0 TSRMLS_CC); + } + + add_next_index_zval(return_value, value); + } + } + } + + xmlXPathFreeObject(retval); +} +/* }}} */ + +/* {{{ proto bool SimpleXMLElement::registerXPathNamespace(string prefix, string ns) + Creates a prefix/ns context for the next XPath query */ +SXE_METHOD(registerXPathNamespace) +{ + php_sxe_object *sxe; + int prefix_len, ns_uri_len; + char *prefix, *ns_uri; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &prefix, &prefix_len, &ns_uri, &ns_uri_len) == FAILURE) { + return; + } + + sxe = php_sxe_fetch_object(getThis() TSRMLS_CC); + if (!sxe->xpath) { + sxe->xpath = xmlXPathNewContext((xmlDocPtr) sxe->document->ptr); + } + + if (xmlXPathRegisterNs(sxe->xpath, (xmlChar *)prefix, (xmlChar *)ns_uri) != 0) { + RETURN_FALSE + } + RETURN_TRUE; +} + +/* }}} */ + +/* {{{ proto string SimpleXMLElement::asXML([string filename]) + Return a well-formed XML string based on SimpleXML element */ +SXE_METHOD(asXML) +{ + php_sxe_object *sxe; + xmlNodePtr node; + xmlOutputBufferPtr outbuf; + xmlChar *strval; + int strval_len; + char *filename; + int filename_len; + + if (ZEND_NUM_ARGS() > 1) { + RETURN_FALSE; + } + + if (ZEND_NUM_ARGS() == 1) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p", &filename, &filename_len) == FAILURE) { + RETURN_FALSE; + } + + sxe = php_sxe_fetch_object(getThis() TSRMLS_CC); + GET_NODE(sxe, node); + node = php_sxe_get_first_node(sxe, node TSRMLS_CC); + + if (node) { + if (node->parent && (XML_DOCUMENT_NODE == node->parent->type)) { + int bytes; + bytes = xmlSaveFile(filename, (xmlDocPtr) sxe->document->ptr); + if (bytes == -1) { + RETURN_FALSE; + } else { + RETURN_TRUE; + } + } else { + outbuf = xmlOutputBufferCreateFilename(filename, NULL, 0); + + if (outbuf == NULL) { + RETURN_FALSE; + } + + xmlNodeDumpOutput(outbuf, (xmlDocPtr) sxe->document->ptr, node, 0, 0, NULL); + xmlOutputBufferClose(outbuf); + RETURN_TRUE; + } + } else { + RETURN_FALSE; + } + } + + sxe = php_sxe_fetch_object(getThis() TSRMLS_CC); + GET_NODE(sxe, node); + node = php_sxe_get_first_node(sxe, node TSRMLS_CC); + + if (node) { + if (node->parent && (XML_DOCUMENT_NODE == node->parent->type)) { + xmlDocDumpMemoryEnc((xmlDocPtr) sxe->document->ptr, &strval, &strval_len, ((xmlDocPtr) sxe->document->ptr)->encoding); + RETVAL_STRINGL((char *)strval, strval_len, 1); + xmlFree(strval); + } else { + /* Should we be passing encoding information instead of NULL? */ + outbuf = xmlAllocOutputBuffer(NULL); + + if (outbuf == NULL) { + RETURN_FALSE; + } + + xmlNodeDumpOutput(outbuf, (xmlDocPtr) sxe->document->ptr, node, 0, 0, ((xmlDocPtr) sxe->document->ptr)->encoding); + xmlOutputBufferFlush(outbuf); +#ifdef LIBXML2_NEW_BUFFER + RETVAL_STRINGL((char *)xmlOutputBufferGetContent(outbuf), xmlOutputBufferGetSize(outbuf), 1); +#else + RETVAL_STRINGL((char *)outbuf->buffer->content, outbuf->buffer->use, 1); +#endif + xmlOutputBufferClose(outbuf); + } + } else { + RETVAL_FALSE; + } +} +/* }}} */ + +#define SXE_NS_PREFIX(ns) (ns->prefix ? (char*)ns->prefix : "") + +static inline void sxe_add_namespace_name(zval *return_value, xmlNsPtr ns) /* {{{ */ +{ + char *prefix = SXE_NS_PREFIX(ns); + if (zend_hash_exists(Z_ARRVAL_P(return_value), prefix, strlen(prefix) + 1) == 0) { + add_assoc_string(return_value, prefix, (char*)ns->href, 1); + } +} +/* }}} */ + +static void sxe_add_namespaces(php_sxe_object *sxe, xmlNodePtr node, zend_bool recursive, zval *return_value TSRMLS_DC) /* {{{ */ +{ + xmlAttrPtr attr; + + if (node->ns) { + sxe_add_namespace_name(return_value, node->ns); + } + + attr = node->properties; + while (attr) { + if (attr->ns) { + sxe_add_namespace_name(return_value, attr->ns); + } + attr = attr->next; + } + + if (recursive) { + node = node->children; + while (node) { + if (node->type == XML_ELEMENT_NODE) { + sxe_add_namespaces(sxe, node, recursive, return_value TSRMLS_CC); + } + node = node->next; + } + } +} /* }}} */ + +/* {{{ proto string SimpleXMLElement::getNamespaces([bool recursve]) + Return all namespaces in use */ +SXE_METHOD(getNamespaces) +{ + zend_bool recursive = 0; + php_sxe_object *sxe; + xmlNodePtr node; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &recursive) == FAILURE) { + return; + } + + array_init(return_value); + + sxe = php_sxe_fetch_object(getThis() TSRMLS_CC); + GET_NODE(sxe, node); + node = php_sxe_get_first_node(sxe, node TSRMLS_CC); + + if (node) { + if (node->type == XML_ELEMENT_NODE) { + sxe_add_namespaces(sxe, node, recursive, return_value TSRMLS_CC); + } else if (node->type == XML_ATTRIBUTE_NODE && node->ns) { + sxe_add_namespace_name(return_value, node->ns); + } + } +} +/* }}} */ + +static void sxe_add_registered_namespaces(php_sxe_object *sxe, xmlNodePtr node, zend_bool recursive, zval *return_value TSRMLS_DC) /* {{{ */ +{ + xmlNsPtr ns; + + if (node->type == XML_ELEMENT_NODE) { + ns = node->nsDef; + while (ns != NULL) { + sxe_add_namespace_name(return_value, ns); + ns = ns->next; + } + if (recursive) { + node = node->children; + while (node) { + sxe_add_registered_namespaces(sxe, node, recursive, return_value TSRMLS_CC); + node = node->next; + } + } + } +} +/* }}} */ + +/* {{{ proto string SimpleXMLElement::getDocNamespaces([bool recursive [, bool from_root]) + Return all namespaces registered with document */ +SXE_METHOD(getDocNamespaces) +{ + zend_bool recursive = 0, from_root = 1; + php_sxe_object *sxe; + xmlNodePtr node; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|bb", &recursive, &from_root) == FAILURE) { + return; + } + + array_init(return_value); + + sxe = php_sxe_fetch_object(getThis() TSRMLS_CC); + if(from_root){ + node = xmlDocGetRootElement((xmlDocPtr)sxe->document->ptr); + }else{ + GET_NODE(sxe, node); + } + + sxe_add_registered_namespaces(sxe, node, recursive, return_value TSRMLS_CC); +} +/* }}} */ + +/* {{{ proto object SimpleXMLElement::children([string ns [, bool is_prefix]]) + Finds children of given node */ +SXE_METHOD(children) +{ + php_sxe_object *sxe; + char *nsprefix = NULL; + int nsprefix_len = 0; + xmlNodePtr node; + zend_bool isprefix = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!b", &nsprefix, &nsprefix_len, &isprefix) == FAILURE) { + return; + } + + sxe = php_sxe_fetch_object(getThis() TSRMLS_CC); + + if (sxe->iter.type == SXE_ITER_ATTRLIST) { + return; /* attributes don't have attributes */ + } + + GET_NODE(sxe, node); + node = php_sxe_get_first_node(sxe, node TSRMLS_CC); + + _node_as_zval(sxe, node, return_value, SXE_ITER_CHILD, NULL, (xmlChar *)nsprefix, isprefix TSRMLS_CC); + +} +/* }}} */ + +/* {{{ proto object SimpleXMLElement::getName() + Finds children of given node */ +SXE_METHOD(getName) +{ + php_sxe_object *sxe; + xmlNodePtr node; + int namelen; + + sxe = php_sxe_fetch_object(getThis() TSRMLS_CC); + + GET_NODE(sxe, node); + node = php_sxe_get_first_node(sxe, node TSRMLS_CC); + if (node) { + namelen = xmlStrlen(node->name); + RETURN_STRINGL((char*)node->name, namelen, 1); + } else { + RETURN_EMPTY_STRING(); + } +} +/* }}} */ + +/* {{{ proto array SimpleXMLElement::attributes([string ns [, bool is_prefix]]) + Identifies an element's attributes */ +SXE_METHOD(attributes) +{ + php_sxe_object *sxe; + char *nsprefix = NULL; + int nsprefix_len = 0; + xmlNodePtr node; + zend_bool isprefix = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!b", &nsprefix, &nsprefix_len, &isprefix) == FAILURE) { + return; + } + + sxe = php_sxe_fetch_object(getThis() TSRMLS_CC); + GET_NODE(sxe, node); + + if (sxe->iter.type == SXE_ITER_ATTRLIST) { + return; /* attributes don't have attributes */ + } + + node = php_sxe_get_first_node(sxe, node TSRMLS_CC); + + _node_as_zval(sxe, node, return_value, SXE_ITER_ATTRLIST, NULL, (xmlChar *)nsprefix, isprefix TSRMLS_CC); +} +/* }}} */ + +/* {{{ proto void SimpleXMLElement::addChild(string qName [, string value [, string ns]]) + Add Element with optional namespace information */ +SXE_METHOD(addChild) +{ + php_sxe_object *sxe; + char *qname, *value = NULL, *nsuri = NULL; + int qname_len, value_len = 0, nsuri_len = 0; + xmlNodePtr node, newnode; + xmlNsPtr nsptr = NULL; + xmlChar *localname, *prefix = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s!s!", + &qname, &qname_len, &value, &value_len, &nsuri, &nsuri_len) == FAILURE) { + return; + } + + if (qname_len == 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Element name is required"); + return; + } + + sxe = php_sxe_fetch_object(getThis() TSRMLS_CC); + GET_NODE(sxe, node); + + if (sxe->iter.type == SXE_ITER_ATTRLIST) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot add element to attributes"); + return; + } + + node = php_sxe_get_first_node(sxe, node TSRMLS_CC); + + if (node == NULL) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot add child. Parent is not a permanent member of the XML tree"); + return; + } + + localname = xmlSplitQName2((xmlChar *)qname, &prefix); + if (localname == NULL) { + localname = xmlStrdup((xmlChar *)qname); + } + + newnode = xmlNewChild(node, NULL, localname, (xmlChar *)value); + + if (nsuri != NULL) { + if (nsuri_len == 0) { + newnode->ns = NULL; + nsptr = xmlNewNs(newnode, (xmlChar *)nsuri, prefix); + } else { + nsptr = xmlSearchNsByHref(node->doc, node, (xmlChar *)nsuri); + if (nsptr == NULL) { + nsptr = xmlNewNs(newnode, (xmlChar *)nsuri, prefix); + } + newnode->ns = nsptr; + } + } + + _node_as_zval(sxe, newnode, return_value, SXE_ITER_NONE, (char *)localname, prefix, 0 TSRMLS_CC); + + xmlFree(localname); + if (prefix != NULL) { + xmlFree(prefix); + } +} +/* }}} */ + +/* {{{ proto void SimpleXMLElement::addAttribute(string qName, string value [,string ns]) + Add Attribute with optional namespace information */ +SXE_METHOD(addAttribute) +{ + php_sxe_object *sxe; + char *qname, *value = NULL, *nsuri = NULL; + int qname_len, value_len = 0, nsuri_len = 0; + xmlNodePtr node; + xmlAttrPtr attrp = NULL; + xmlNsPtr nsptr = NULL; + xmlChar *localname, *prefix = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|s!", + &qname, &qname_len, &value, &value_len, &nsuri, &nsuri_len) == FAILURE) { + return; + } + + if (qname_len == 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attribute name is required"); + return; + } + + sxe = php_sxe_fetch_object(getThis() TSRMLS_CC); + GET_NODE(sxe, node); + + node = php_sxe_get_first_node(sxe, node TSRMLS_CC); + + if (node && node->type != XML_ELEMENT_NODE) { + node = node->parent; + } + + if (node == NULL) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to locate parent Element"); + return; + } + + localname = xmlSplitQName2((xmlChar *)qname, &prefix); + if (localname == NULL) { + if (nsuri_len > 0) { + if (prefix != NULL) { + xmlFree(prefix); + } + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attribute requires prefix for namespace"); + return; + } + localname = xmlStrdup((xmlChar *)qname); + } + + attrp = xmlHasNsProp(node, localname, (xmlChar *)nsuri); + if (attrp != NULL && attrp->type != XML_ATTRIBUTE_DECL) { + xmlFree(localname); + if (prefix != NULL) { + xmlFree(prefix); + } + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attribute already exists"); + return; + } + + if (nsuri != NULL) { + nsptr = xmlSearchNsByHref(node->doc, node, (xmlChar *)nsuri); + if (nsptr == NULL) { + nsptr = xmlNewNs(node, (xmlChar *)nsuri, prefix); + } + } + + attrp = xmlNewNsProp(node, nsptr, localname, (xmlChar *)value); + + xmlFree(localname); + if (prefix != NULL) { + xmlFree(prefix); + } +} +/* }}} */ + +/* {{{ cast_object() + */ +static int cast_object(zval *object, int type, char *contents TSRMLS_DC) +{ + if (contents) { + ZVAL_STRINGL(object, contents, strlen(contents), 1); + } else { + ZVAL_NULL(object); + } + Z_SET_REFCOUNT_P(object, 1); + Z_UNSET_ISREF_P(object); + + switch (type) { + case IS_STRING: + convert_to_string(object); + break; + case IS_BOOL: + convert_to_boolean(object); + break; + case IS_LONG: + convert_to_long(object); + break; + case IS_DOUBLE: + convert_to_double(object); + break; + default: + return FAILURE; + } + return SUCCESS; +} +/* }}} */ + +/* {{{ sxe_object_cast() + */ +static int sxe_object_cast(zval *readobj, zval *writeobj, int type TSRMLS_DC) +{ + php_sxe_object *sxe; + xmlChar *contents = NULL; + xmlNodePtr node; + int rv; + HashTable *prop_hash; + + sxe = php_sxe_fetch_object(readobj TSRMLS_CC); + + if (type == IS_BOOL) { + node = php_sxe_get_first_node(sxe, NULL TSRMLS_CC); + prop_hash = sxe_get_prop_hash(readobj, 1 TSRMLS_CC); + INIT_PZVAL(writeobj); + ZVAL_BOOL(writeobj, node != NULL || zend_hash_num_elements(prop_hash) > 0); + zend_hash_destroy(prop_hash); + efree(prop_hash); + return SUCCESS; + } + + 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 (readobj == writeobj) { + INIT_PZVAL(writeobj); + zval_dtor(readobj); + } + + rv = cast_object(writeobj, type, (char *)contents TSRMLS_CC); + + if (contents) { + xmlFree(contents); + } + return rv; +} +/* }}} */ + +/* {{{ proto object SimpleXMLElement::__toString() U + Returns the string content */ +SXE_METHOD(__toString) +{ + zval *result; + + ALLOC_INIT_ZVAL(result); + + if (sxe_object_cast(getThis(), result, IS_STRING TSRMLS_CC) == SUCCESS) { + RETURN_ZVAL(result, 1, 1); + } else { + zval_ptr_dtor(&result); + RETURN_EMPTY_STRING(); + } +} +/* }}} */ + +static int php_sxe_count_elements_helper(php_sxe_object *sxe, long *count TSRMLS_DC) /* {{{ */ +{ + xmlNodePtr node; + zval *data; + + *count = 0; + + data = sxe->iter.data; + sxe->iter.data = NULL; + + node = php_sxe_reset_iterator(sxe, 0 TSRMLS_CC); + + while (node) + { + (*count)++; + node = php_sxe_iterator_fetch(sxe, node->next, 0 TSRMLS_CC); + } + + if (sxe->iter.data) { + zval_ptr_dtor(&sxe->iter.data); + } + sxe->iter.data = data; + + return SUCCESS; +} +/* }}} */ + +static int sxe_count_elements(zval *object, long *count TSRMLS_DC) /* {{{ */ +{ + php_sxe_object *intern; + intern = php_sxe_fetch_object(object TSRMLS_CC); + if (intern->fptr_count) { + zval *rv; + zend_call_method_with_0_params(&object, intern->zo.ce, &intern->fptr_count, "count", &rv); + if (rv) { + if (intern->tmp) { + zval_ptr_dtor(&intern->tmp); + } + MAKE_STD_ZVAL(intern->tmp); + ZVAL_ZVAL(intern->tmp, rv, 1, 1); + convert_to_long(intern->tmp); + *count = (long) Z_LVAL_P(intern->tmp); + return SUCCESS; + } + return FAILURE; + } + return php_sxe_count_elements_helper(intern, count TSRMLS_CC); +} +/* }}} */ + +/* {{{ proto int SimpleXMLElement::count() + Get number of child elements */ +SXE_METHOD(count) +{ + long count = 0; + php_sxe_object *sxe = php_sxe_fetch_object(getThis() TSRMLS_CC); + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + php_sxe_count_elements_helper(sxe, &count TSRMLS_CC); + + RETURN_LONG(count); +} +/* }}} */ + +static zval *sxe_get_value(zval *z TSRMLS_DC) /* {{{ */ +{ + zval *retval; + + MAKE_STD_ZVAL(retval); + + if (sxe_object_cast(z, retval, IS_STRING TSRMLS_CC)==FAILURE) { + zend_error(E_ERROR, "Unable to cast node to string"); + /* FIXME: Should not be fatal */ + } + + Z_SET_REFCOUNT_P(retval, 0); + return retval; +} +/* }}} */ + +static zend_object_handlers sxe_object_handlers = { /* {{{ */ + ZEND_OBJECTS_STORE_HANDLERS, + sxe_property_read, + sxe_property_write, + sxe_dimension_read, + sxe_dimension_write, + sxe_property_get_adr, + sxe_get_value, /* get */ + NULL, + sxe_property_exists, + sxe_property_delete, + sxe_dimension_exists, + sxe_dimension_delete, + sxe_get_properties, + NULL, /* zend_get_std_object_handlers()->get_method,*/ + NULL, /* zend_get_std_object_handlers()->call_method,*/ + NULL, /* zend_get_std_object_handlers()->get_constructor, */ + NULL, /* zend_get_std_object_handlers()->get_class_entry,*/ + NULL, /* zend_get_std_object_handlers()->get_class_name,*/ + sxe_objects_compare, + sxe_object_cast, + sxe_count_elements, + sxe_get_debug_info, + NULL, + sxe_get_gc +}; +/* }}} */ + +/* {{{ sxe_object_clone() + */ +static void +sxe_object_clone(void *object, void **clone_ptr TSRMLS_DC) +{ + php_sxe_object *sxe = (php_sxe_object *) object; + php_sxe_object *clone; + xmlNodePtr nodep = NULL; + xmlDocPtr docp = NULL; + + clone = php_sxe_object_new(sxe->zo.ce TSRMLS_CC); + clone->document = sxe->document; + if (clone->document) { + clone->document->refcount++; + docp = clone->document->ptr; + } + + clone->iter.isprefix = sxe->iter.isprefix; + if (sxe->iter.name != NULL) { + clone->iter.name = xmlStrdup((xmlChar *)sxe->iter.name); + } + if (sxe->iter.nsprefix != NULL) { + clone->iter.nsprefix = xmlStrdup((xmlChar *)sxe->iter.nsprefix); + } + clone->iter.type = sxe->iter.type; + + if (sxe->node) { + nodep = xmlDocCopyNode(sxe->node->node, docp, 1); + } + + php_libxml_increment_node_ptr((php_libxml_node_object *)clone, nodep, NULL TSRMLS_CC); + + *clone_ptr = (void *) clone; +} +/* }}} */ + +/* {{{ sxe_object_dtor() + */ +static void sxe_object_dtor(void *object, zend_object_handle handle TSRMLS_DC) +{ + /* dtor required to cleanup iterator related data properly */ + + php_sxe_object *sxe; + + sxe = (php_sxe_object *) object; + + if (sxe->iter.data) { + zval_ptr_dtor(&sxe->iter.data); + sxe->iter.data = NULL; + } + + if (sxe->iter.name) { + xmlFree(sxe->iter.name); + sxe->iter.name = NULL; + } + if (sxe->iter.nsprefix) { + xmlFree(sxe->iter.nsprefix); + sxe->iter.nsprefix = NULL; + } + if (sxe->tmp) { + zval_ptr_dtor(&sxe->tmp); + sxe->tmp = NULL; + } +} +/* }}} */ + +/* {{{ sxe_object_free_storage() + */ +static void sxe_object_free_storage(void *object TSRMLS_DC) +{ + php_sxe_object *sxe; + + sxe = (php_sxe_object *) object; + +#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION == 1 && PHP_RELEASE_VERSION > 2) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 1) || (PHP_MAJOR_VERSION > 5) + zend_object_std_dtor(&sxe->zo TSRMLS_CC); +#else + if (sxe->zo.guards) { + zend_hash_destroy(sxe->zo.guards); + FREE_HASHTABLE(sxe->zo.guards); + } + + if (sxe->zo.properties) { + zend_hash_destroy(sxe->zo.properties); + FREE_HASHTABLE(sxe->zo.properties); + } +#endif + + php_libxml_node_decrement_resource((php_libxml_node_object *)sxe TSRMLS_CC); + + if (sxe->xpath) { + xmlXPathFreeContext(sxe->xpath); + } + + if (sxe->properties) { + zend_hash_destroy(sxe->properties); + FREE_HASHTABLE(sxe->properties); + } + + efree(object); +} +/* }}} */ + +/* {{{ php_sxe_object_new() + */ +static php_sxe_object* php_sxe_object_new(zend_class_entry *ce TSRMLS_DC) +{ + php_sxe_object *intern; + zend_class_entry *parent = ce; + int inherited = 0; + + intern = ecalloc(1, sizeof(php_sxe_object)); + + intern->iter.type = SXE_ITER_NONE; + intern->iter.nsprefix = NULL; + intern->iter.name = NULL; + intern->fptr_count = NULL; + +#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION == 1 && PHP_RELEASE_VERSION > 2) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 1) || (PHP_MAJOR_VERSION > 5) + zend_object_std_init(&intern->zo, ce TSRMLS_CC); +#else + ALLOC_HASHTABLE(intern->zo.properties); + zend_hash_init(intern->zo.properties, 0, NULL, ZVAL_PTR_DTOR, 0); + + intern->zo.ce = ce; + intern->zo.guards = NULL; +#endif + + while (parent) { + if (parent == sxe_class_entry) { + break; + } + + parent = parent->parent; + inherited = 1; + } + + if (inherited) { + zend_hash_find(&ce->function_table, "count", sizeof("count"),(void **) &intern->fptr_count); + if (intern->fptr_count->common.scope == parent) { + intern->fptr_count = NULL; + } + } + + return intern; +} +/* }}} */ + +/* {{{ php_sxe_register_object + */ +static zend_object_value +php_sxe_register_object(php_sxe_object *intern TSRMLS_DC) +{ + zend_object_value rv; + + rv.handle = zend_objects_store_put(intern, sxe_object_dtor, (zend_objects_free_object_storage_t)sxe_object_free_storage, sxe_object_clone TSRMLS_CC); + rv.handlers = (zend_object_handlers *) &sxe_object_handlers; + + return rv; +} +/* }}} */ + +/* {{{ sxe_object_new() + */ +PHP_SXE_API zend_object_value +sxe_object_new(zend_class_entry *ce TSRMLS_DC) +{ + php_sxe_object *intern; + + intern = php_sxe_object_new(ce TSRMLS_CC); + return php_sxe_register_object(intern TSRMLS_CC); +} +/* }}} */ + +/* {{{ proto simplemxml_element simplexml_load_file(string filename [, string class_name [, int options [, string ns [, bool is_prefix]]]]) + Load a filename and return a simplexml_element object to allow for processing */ +PHP_FUNCTION(simplexml_load_file) +{ + php_sxe_object *sxe; + char *filename; + int filename_len; + xmlDocPtr docp; + char *ns = NULL; + int ns_len = 0; + long options = 0; + zend_class_entry *ce= sxe_class_entry; + zend_bool isprefix = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|C!lsb", &filename, &filename_len, &ce, &options, &ns, &ns_len, &isprefix) == FAILURE) { + return; + } + + docp = xmlReadFile(filename, NULL, options); + + if (! docp) { + RETURN_FALSE; + } + + if (!ce) { + ce = sxe_class_entry; + } + sxe = php_sxe_object_new(ce TSRMLS_CC); + sxe->iter.nsprefix = ns_len ? xmlStrdup((xmlChar *)ns) : NULL; + sxe->iter.isprefix = isprefix; + php_libxml_increment_doc_ref((php_libxml_node_object *)sxe, docp TSRMLS_CC); + php_libxml_increment_node_ptr((php_libxml_node_object *)sxe, xmlDocGetRootElement(docp), NULL TSRMLS_CC); + + return_value->type = IS_OBJECT; + return_value->value.obj = php_sxe_register_object(sxe TSRMLS_CC); +} +/* }}} */ + +/* {{{ proto simplemxml_element simplexml_load_string(string data [, string class_name [, int options [, string ns [, bool is_prefix]]]]) + Load a string and return a simplexml_element object to allow for processing */ +PHP_FUNCTION(simplexml_load_string) +{ + php_sxe_object *sxe; + char *data; + int data_len; + xmlDocPtr docp; + char *ns = NULL; + int ns_len = 0; + long options = 0; + zend_class_entry *ce= sxe_class_entry; + zend_bool isprefix = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|C!lsb", &data, &data_len, &ce, &options, &ns, &ns_len, &isprefix) == FAILURE) { + return; + } + + docp = xmlReadMemory(data, data_len, NULL, NULL, options); + + if (! docp) { + RETURN_FALSE; + } + + if (!ce) { + ce = sxe_class_entry; + } + sxe = php_sxe_object_new(ce TSRMLS_CC); + sxe->iter.nsprefix = ns_len ? xmlStrdup((xmlChar *)ns) : NULL; + sxe->iter.isprefix = isprefix; + php_libxml_increment_doc_ref((php_libxml_node_object *)sxe, docp TSRMLS_CC); + php_libxml_increment_node_ptr((php_libxml_node_object *)sxe, xmlDocGetRootElement(docp), NULL TSRMLS_CC); + + return_value->type = IS_OBJECT; + return_value->value.obj = php_sxe_register_object(sxe TSRMLS_CC); +} +/* }}} */ + +/* {{{ proto SimpleXMLElement::__construct(string data [, int options [, bool data_is_url [, string ns [, bool is_prefix]]]]) + SimpleXMLElement constructor */ +SXE_METHOD(__construct) +{ + php_sxe_object *sxe = php_sxe_fetch_object(getThis() TSRMLS_CC); + char *data, *ns = NULL; + int data_len, ns_len = 0; + xmlDocPtr docp; + long options = 0; + zend_bool is_url = 0, isprefix = 0; + zend_error_handling error_handling; + + zend_replace_error_handling(EH_THROW, NULL, &error_handling TSRMLS_CC); + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lbsb", &data, &data_len, &options, &is_url, &ns, &ns_len, &isprefix) == FAILURE) { + zend_restore_error_handling(&error_handling TSRMLS_CC); + return; + } + + zend_restore_error_handling(&error_handling TSRMLS_CC); + + docp = is_url ? xmlReadFile(data, NULL, options) : xmlReadMemory(data, data_len, NULL, NULL, options); + + if (!docp) { + ((php_libxml_node_object *)sxe)->document = NULL; + zend_throw_exception(zend_exception_get_default(TSRMLS_C), "String could not be parsed as XML", 0 TSRMLS_CC); + return; + } + + sxe->iter.nsprefix = ns_len ? xmlStrdup((xmlChar *)ns) : NULL; + sxe->iter.isprefix = isprefix; + php_libxml_increment_doc_ref((php_libxml_node_object *)sxe, docp TSRMLS_CC); + php_libxml_increment_node_ptr((php_libxml_node_object *)sxe, xmlDocGetRootElement(docp), NULL TSRMLS_CC); +} +/* }}} */ + +zend_object_iterator_funcs php_sxe_iterator_funcs = { /* {{{ */ + php_sxe_iterator_dtor, + php_sxe_iterator_valid, + php_sxe_iterator_current_data, + php_sxe_iterator_current_key, + php_sxe_iterator_move_forward, + php_sxe_iterator_rewind, +}; +/* }}} */ + +static xmlNodePtr php_sxe_iterator_fetch(php_sxe_object *sxe, xmlNodePtr node, int use_data TSRMLS_DC) /* {{{ */ +{ + xmlChar *prefix = sxe->iter.nsprefix; + int isprefix = sxe->iter.isprefix; + int test_elem = sxe->iter.type == SXE_ITER_ELEMENT && sxe->iter.name; + int test_attr = sxe->iter.type == SXE_ITER_ATTRLIST && sxe->iter.name; + + while (node) { + SKIP_TEXT(node); + if (sxe->iter.type != SXE_ITER_ATTRLIST && node->type == XML_ELEMENT_NODE) { + if ((!test_elem || !xmlStrcmp(node->name, sxe->iter.name)) && match_ns(sxe, node, prefix, isprefix)) { + break; + } + } else if (node->type == XML_ATTRIBUTE_NODE) { + if ((!test_attr || !xmlStrcmp(node->name, sxe->iter.name)) && match_ns(sxe, node, prefix, isprefix)) { + break; + } + } +next_iter: + node = node->next; + } + + if (node && use_data) { + ALLOC_INIT_ZVAL(sxe->iter.data); + _node_as_zval(sxe, node, sxe->iter.data, SXE_ITER_NONE, NULL, prefix, isprefix TSRMLS_CC); + } + + return node; +} +/* }}} */ + +static xmlNodePtr php_sxe_reset_iterator(php_sxe_object *sxe, int use_data TSRMLS_DC) /* {{{ */ +{ + xmlNodePtr node; + + 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_ATTRLIST: + node = (xmlNodePtr) node->properties; + } + return php_sxe_iterator_fetch(sxe, node, use_data TSRMLS_CC); + } + return NULL; +} +/* }}} */ + +zend_object_iterator *php_sxe_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC) /* {{{ */ +{ + php_sxe_iterator *iterator; + + if (by_ref) { + zend_error(E_ERROR, "An iterator cannot be used with foreach by reference"); + } + iterator = emalloc(sizeof(php_sxe_iterator)); + + Z_ADDREF_P(object); + iterator->intern.data = (void*)object; + iterator->intern.funcs = &php_sxe_iterator_funcs; + iterator->sxe = php_sxe_fetch_object(object TSRMLS_CC); + + return (zend_object_iterator*)iterator; +} +/* }}} */ + +static void php_sxe_iterator_dtor(zend_object_iterator *iter TSRMLS_DC) /* {{{ */ +{ + php_sxe_iterator *iterator = (php_sxe_iterator *)iter; + + /* cleanup handled in sxe_object_dtor as we dont always have an iterator wrapper */ + if (iterator->intern.data) { + zval_ptr_dtor((zval**)&iterator->intern.data); + } + + efree(iterator); +} +/* }}} */ + +static int php_sxe_iterator_valid(zend_object_iterator *iter TSRMLS_DC) /* {{{ */ +{ + php_sxe_iterator *iterator = (php_sxe_iterator *)iter; + + return iterator->sxe->iter.data ? SUCCESS : FAILURE; +} +/* }}} */ + +static void php_sxe_iterator_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC) /* {{{ */ +{ + php_sxe_iterator *iterator = (php_sxe_iterator *)iter; + + *data = &iterator->sxe->iter.data; +} +/* }}} */ + +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; + 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; + } + if (!curnode) { + return HASH_KEY_NON_EXISTANT; + } + + namelen = xmlStrlen(curnode->name); + *str_key = estrndup((char *)curnode->name, namelen); + *str_key_len = namelen + 1; + return HASH_KEY_IS_STRING; + +} +/* }}} */ + +PHP_SXE_API void php_sxe_move_forward_iterator(php_sxe_object *sxe TSRMLS_DC) /* {{{ */ +{ + xmlNodePtr node = NULL; + php_sxe_object *intern; + + 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; + } + + if (node) { + php_sxe_iterator_fetch(sxe, node->next, 1 TSRMLS_CC); + } +} +/* }}} */ + +static void php_sxe_iterator_move_forward(zend_object_iterator *iter TSRMLS_DC) /* {{{ */ +{ + php_sxe_iterator *iterator = (php_sxe_iterator *)iter; + php_sxe_move_forward_iterator(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; + sxe = iterator->sxe; + + php_sxe_reset_iterator(sxe, 1 TSRMLS_CC); +} +/* }}} */ + +void *simplexml_export_node(zval *object TSRMLS_DC) /* {{{ */ +{ + php_sxe_object *sxe; + xmlNodePtr node; + + sxe = php_sxe_fetch_object(object TSRMLS_CC); + GET_NODE(sxe, node); + return php_sxe_get_first_node(sxe, node TSRMLS_CC); +} +/* }}} */ + +/* {{{ proto simplemxml_element simplexml_import_dom(domNode node [, string class_name]) + Get a simplexml_element object from dom to allow for processing */ +PHP_FUNCTION(simplexml_import_dom) +{ + php_sxe_object *sxe; + zval *node; + php_libxml_node_object *object; + xmlNodePtr nodep = NULL; + zend_class_entry *ce= sxe_class_entry; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o|C!", &node, &ce) == FAILURE) { + return; + } + + object = (php_libxml_node_object *)zend_object_store_get_object(node TSRMLS_CC); + + nodep = php_libxml_import_node(node TSRMLS_CC); + + if (nodep) { + if (nodep->doc == NULL) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Imported Node must have associated Document"); + RETURN_NULL(); + } + if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) { + nodep = xmlDocGetRootElement((xmlDocPtr) nodep); + } + } + + if (nodep && nodep->type == XML_ELEMENT_NODE) { + if (!ce) { + ce = sxe_class_entry; + } + sxe = php_sxe_object_new(ce TSRMLS_CC); + sxe->document = object->document; + php_libxml_increment_doc_ref((php_libxml_node_object *)sxe, nodep->doc TSRMLS_CC); + php_libxml_increment_node_ptr((php_libxml_node_object *)sxe, nodep, NULL TSRMLS_CC); + + return_value->type = IS_OBJECT; + return_value->value.obj = php_sxe_register_object(sxe TSRMLS_CC); + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Nodetype to import"); + RETVAL_NULL(); + } +} +/* }}} */ + +/* {{{ arginfo */ +ZEND_BEGIN_ARG_INFO_EX(arginfo_simplexml_load_file, 0, 0, 1) + ZEND_ARG_INFO(0, filename) + ZEND_ARG_INFO(0, class_name) + ZEND_ARG_INFO(0, options) + ZEND_ARG_INFO(0, ns) + ZEND_ARG_INFO(0, is_prefix) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_simplexml_load_string, 0, 0, 1) + ZEND_ARG_INFO(0, data) + ZEND_ARG_INFO(0, class_name) + ZEND_ARG_INFO(0, options) + ZEND_ARG_INFO(0, ns) + ZEND_ARG_INFO(0, is_prefix) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_simplexml_import_dom, 0, 0, 1) + ZEND_ARG_INFO(0, node) + ZEND_ARG_INFO(0, class_name) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_simplexmlelement_xpath, 0, 0, 1) + ZEND_ARG_INFO(0, path) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_simplexmlelement_registerxpathnamespace, 0, 0, 2) + ZEND_ARG_INFO(0, prefix) + ZEND_ARG_INFO(0, ns) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_simplexmlelement_asxml, 0, 0, 0) + ZEND_ARG_INFO(0, filename) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_simplexmlelement_getnamespaces, 0, 0, 0) + ZEND_ARG_INFO(0, recursve) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_simplexmlelement_getdocnamespaces, 0, 0, 0) + ZEND_ARG_INFO(0, recursve) + ZEND_ARG_INFO(0, from_root) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_simplexmlelement_children, 0, 0, 0) + ZEND_ARG_INFO(0, ns) + ZEND_ARG_INFO(0, is_prefix) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_simplexmlelement__construct, 0, 0, 1) + ZEND_ARG_INFO(0, data) + ZEND_ARG_INFO(0, options) + ZEND_ARG_INFO(0, data_is_url) + ZEND_ARG_INFO(0, ns) + ZEND_ARG_INFO(0, is_prefix) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_simplexmlelement__void, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_simplexmlelement_addchild, 0, 0, 1) + ZEND_ARG_INFO(0, name) + ZEND_ARG_INFO(0, value) + ZEND_ARG_INFO(0, ns) +ZEND_END_ARG_INFO() +/* }}} */ + +const zend_function_entry simplexml_functions[] = { /* {{{ */ + PHP_FE(simplexml_load_file, arginfo_simplexml_load_file) + PHP_FE(simplexml_load_string, arginfo_simplexml_load_string) + PHP_FE(simplexml_import_dom, arginfo_simplexml_import_dom) + PHP_FE_END +}; +/* }}} */ + +static const zend_module_dep simplexml_deps[] = { /* {{{ */ + ZEND_MOD_REQUIRED("libxml") + ZEND_MOD_REQUIRED("spl") + ZEND_MOD_END +}; +/* }}} */ + +zend_module_entry simplexml_module_entry = { /* {{{ */ + STANDARD_MODULE_HEADER_EX, NULL, + simplexml_deps, + "SimpleXML", + simplexml_functions, + PHP_MINIT(simplexml), + PHP_MSHUTDOWN(simplexml), + NULL, + NULL, + PHP_MINFO(simplexml), + "0.1", + STANDARD_MODULE_PROPERTIES +}; +/* }}} */ + +#ifdef COMPILE_DL_SIMPLEXML +ZEND_GET_MODULE(simplexml) +#endif + +/* the method table */ +/* each method can have its own parameters and visibility */ +static const zend_function_entry sxe_functions[] = { /* {{{ */ + SXE_ME(__construct, arginfo_simplexmlelement__construct, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) /* must be called */ + SXE_ME(asXML, arginfo_simplexmlelement_asxml, ZEND_ACC_PUBLIC) + SXE_MALIAS(saveXML, asXML, arginfo_simplexmlelement_asxml, ZEND_ACC_PUBLIC) + SXE_ME(xpath, arginfo_simplexmlelement_xpath, ZEND_ACC_PUBLIC) + SXE_ME(registerXPathNamespace, arginfo_simplexmlelement_registerxpathnamespace, ZEND_ACC_PUBLIC) + SXE_ME(attributes, arginfo_simplexmlelement_children, ZEND_ACC_PUBLIC) + SXE_ME(children, arginfo_simplexmlelement_children, ZEND_ACC_PUBLIC) + SXE_ME(getNamespaces, arginfo_simplexmlelement_getnamespaces, ZEND_ACC_PUBLIC) + SXE_ME(getDocNamespaces, arginfo_simplexmlelement_getdocnamespaces, ZEND_ACC_PUBLIC) + SXE_ME(getName, arginfo_simplexmlelement__void, ZEND_ACC_PUBLIC) + SXE_ME(addChild, arginfo_simplexmlelement_addchild, ZEND_ACC_PUBLIC) + SXE_ME(addAttribute, arginfo_simplexmlelement_addchild, ZEND_ACC_PUBLIC) + SXE_ME(__toString, arginfo_simplexmlelement__void, ZEND_ACC_PUBLIC) + SXE_ME(count, arginfo_simplexmlelement__void, ZEND_ACC_PUBLIC) + PHP_FE_END +}; +/* }}} */ + +/* {{{ PHP_MINIT_FUNCTION(simplexml) + */ +PHP_MINIT_FUNCTION(simplexml) +{ + zend_class_entry sxe; + + INIT_CLASS_ENTRY(sxe, "SimpleXMLElement", sxe_functions); + sxe.create_object = sxe_object_new; + sxe_class_entry = zend_register_internal_class(&sxe TSRMLS_CC); + sxe_class_entry->get_iterator = php_sxe_get_iterator; + sxe_class_entry->iterator_funcs.funcs = &php_sxe_iterator_funcs; + zend_class_implements(sxe_class_entry TSRMLS_CC, 1, zend_ce_traversable); + sxe_object_handlers.get_method = zend_get_std_object_handlers()->get_method; + sxe_object_handlers.get_constructor = zend_get_std_object_handlers()->get_constructor; + sxe_object_handlers.get_class_entry = zend_get_std_object_handlers()->get_class_entry; + sxe_object_handlers.get_class_name = zend_get_std_object_handlers()->get_class_name; + sxe_class_entry->serialize = zend_class_serialize_deny; + sxe_class_entry->unserialize = zend_class_unserialize_deny; + + php_libxml_register_export(sxe_class_entry, simplexml_export_node); + + PHP_MINIT(sxe)(INIT_FUNC_ARGS_PASSTHRU); + + return SUCCESS; +} +/* }}} */ + +/* {{{ PHP_MSHUTDOWN_FUNCTION(simplexml) + */ +PHP_MSHUTDOWN_FUNCTION(simplexml) +{ + sxe_class_entry = NULL; + return SUCCESS; +} +/* }}} */ + +/* {{{ PHP_MINFO_FUNCTION(simplexml) + */ +PHP_MINFO_FUNCTION(simplexml) +{ + php_info_print_table_start(); + php_info_print_table_header(2, "Simplexml support", "enabled"); + php_info_print_table_row(2, "Revision", "$Id: 692516840b2d7d6e7aedb0bedded1f53b764a99f $"); + php_info_print_table_row(2, "Schema support", +#ifdef LIBXML_SCHEMAS_ENABLED + "enabled"); +#else + "not available"); +#endif + php_info_print_table_end(); +} +/* }}} */ + +#endif + +/** + * Local Variables: + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: t + * End: + * vim600: fdm=marker + * vim: noet sw=4 ts=4 + */ diff --git a/ext/simplexml/simplexml.dsp b/ext/simplexml/simplexml.dsp new file mode 100644 index 0000000..79df918 --- /dev/null +++ b/ext/simplexml/simplexml.dsp @@ -0,0 +1,111 @@ +# Microsoft Developer Studio Project File - Name="simplexml" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=simplexml - Win32 Debug_TS
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "simplexml.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "simplexml.mak" CFG="simplexml - Win32 Debug_TS"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "simplexml - Win32 Debug_TS" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "simplexml - Win32 Release_TS" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "simplexml - Win32 Debug_TS"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug_TS"
+# PROP BASE Intermediate_Dir "Debug_TS"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "c:\php\5d\extensions"
+# PROP Intermediate_Dir "Debug_TS"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SIMPLEXML_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\php5" /I "..\..\..\php5\main" /I "..\..\..\php5\Zend" /I "..\..\..\php5\TSRM" /D ZEND_DEBUG=1 /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D COMPILE_DL_SIMPLEXML=1 /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SIMPLEXML_EXPORTS" /D "LIBXML_THREAD_ENABLED" /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 php5ts_debug.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\php5\Debug_TS"
+
+!ELSEIF "$(CFG)" == "simplexml - Win32 Release_TS"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release_TS"
+# PROP BASE Intermediate_Dir "Release_TS"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release_TS"
+# PROP Intermediate_Dir "Release_TS"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SIMPLEXML_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\..\php5\main" /I "..\..\..\php5\Zend" /I "..\..\..\php5\TSRM" /I "..\..\..\php5\win32" /I "..\..\..\php5" /D ZTS=1 /D ZEND_DEBUG=0 /D "ZEND_WIN32" /D "PHP_WIN32" /D COMPILE_DL_SIMPLEXML=1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SIMPLEXML_EXPORTS" /D "LIBXML_THREAD_ENABLED" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 php5ts.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /libpath:"..\..\..\php5\Release_TS" /libpath:"..\..\..\php5\Release_TS_Inline"
+
+!ENDIF
+
+# Begin Target
+
+# Name "simplexml - Win32 Debug_TS"
+# Name "simplexml - Win32 Release_TS"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\simplexml.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\php_simplexml.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/ext/simplexml/sxe.c b/ext/simplexml/sxe.c new file mode 100644 index 0000000..e3278da --- /dev/null +++ b/ext/simplexml/sxe.c @@ -0,0 +1,219 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Marcus Boerger <helly@php.net> | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "php.h" +#include "php_ini.h" +#include "ext/standard/info.h" +#include "zend_interfaces.h" + +#include "ext/spl/php_spl.h" +#include "ext/spl/spl_iterators.h" +#include "sxe.h" + +zend_class_entry *ce_SimpleXMLIterator = NULL; +zend_class_entry *ce_SimpleXMLElement; + +#include "php_simplexml_exports.h" + +/* {{{ proto void SimpleXMLIterator::rewind() + Rewind to first element */ +PHP_METHOD(ce_SimpleXMLIterator, rewind) +{ + php_sxe_iterator iter; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + iter.sxe = php_sxe_fetch_object(getThis() TSRMLS_CC); + ce_SimpleXMLElement->iterator_funcs.funcs->rewind((zend_object_iterator*)&iter TSRMLS_CC); +} +/* }}} */ + +/* {{{ proto bool SimpleXMLIterator::valid() + Check whether iteration is valid */ +PHP_METHOD(ce_SimpleXMLIterator, valid) +{ + php_sxe_object *sxe = php_sxe_fetch_object(getThis() TSRMLS_CC); + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + RETURN_BOOL(sxe->iter.data); +} +/* }}} */ + +/* {{{ proto SimpleXMLIterator SimpleXMLIterator::current() + Get current element */ +PHP_METHOD(ce_SimpleXMLIterator, current) +{ + php_sxe_object *sxe = php_sxe_fetch_object(getThis() TSRMLS_CC); + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + if (!sxe->iter.data) { + return; /* return NULL */ + } + + RETURN_ZVAL(sxe->iter.data, 1, 0); +} +/* }}} */ + +/* {{{ proto string SimpleXMLIterator::key() + Get name of current child element */ +PHP_METHOD(ce_SimpleXMLIterator, key) +{ + xmlNodePtr curnode; + php_sxe_object *intern; + php_sxe_object *sxe = php_sxe_fetch_object(getThis() TSRMLS_CC); + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + if (!sxe->iter.data) { + RETURN_FALSE; + } + + intern = (php_sxe_object *)zend_object_store_get_object(sxe->iter.data TSRMLS_CC); + if (intern != NULL && intern->node != NULL) { + curnode = (xmlNodePtr)((php_libxml_node_ptr *)intern->node)->node; + RETURN_STRINGL((char*)curnode->name, xmlStrlen(curnode->name), 1); + } + + RETURN_FALSE; +} +/* }}} */ + +/* {{{ proto void SimpleXMLIterator::next() + Move to next element */ +PHP_METHOD(ce_SimpleXMLIterator, next) +{ + php_sxe_iterator iter; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + iter.sxe = php_sxe_fetch_object(getThis() TSRMLS_CC); + ce_SimpleXMLElement->iterator_funcs.funcs->move_forward((zend_object_iterator*)&iter TSRMLS_CC); +} +/* }}} */ + +/* {{{ proto bool SimpleXMLIterator::hasChildren() + Check whether element has children (elements) */ +PHP_METHOD(ce_SimpleXMLIterator, hasChildren) +{ + php_sxe_object *sxe = php_sxe_fetch_object(getThis() TSRMLS_CC); + php_sxe_object *child; + xmlNodePtr node; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + if (!sxe->iter.data || sxe->iter.type == SXE_ITER_ATTRLIST) { + RETURN_FALSE; + } + child = php_sxe_fetch_object(sxe->iter.data TSRMLS_CC); + + GET_NODE(child, node); + if (node) { + node = node->children; + } + while (node && node->type != XML_ELEMENT_NODE) { + node = node->next; + } + RETURN_BOOL(node ? 1 : 0); +} +/* }}} */ + +/* {{{ proto SimpleXMLIterator SimpleXMLIterator::getChildren() + Get child element iterator */ +PHP_METHOD(ce_SimpleXMLIterator, getChildren) +{ + php_sxe_object *sxe = php_sxe_fetch_object(getThis() TSRMLS_CC); + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + if (!sxe->iter.data || sxe->iter.type == SXE_ITER_ATTRLIST) { + return; /* return NULL */ + } + RETURN_ZVAL(sxe->iter.data, 1, 0); +} + +/* {{{ arginfo */ +ZEND_BEGIN_ARG_INFO(arginfo_simplexmliterator__void, 0) +ZEND_END_ARG_INFO() +/* }}} */ + +static const zend_function_entry funcs_SimpleXMLIterator[] = { + PHP_ME(ce_SimpleXMLIterator, rewind, arginfo_simplexmliterator__void, ZEND_ACC_PUBLIC) + PHP_ME(ce_SimpleXMLIterator, valid, arginfo_simplexmliterator__void, ZEND_ACC_PUBLIC) + PHP_ME(ce_SimpleXMLIterator, current, arginfo_simplexmliterator__void, ZEND_ACC_PUBLIC) + PHP_ME(ce_SimpleXMLIterator, key, arginfo_simplexmliterator__void, ZEND_ACC_PUBLIC) + PHP_ME(ce_SimpleXMLIterator, next, arginfo_simplexmliterator__void, ZEND_ACC_PUBLIC) + PHP_ME(ce_SimpleXMLIterator, hasChildren, arginfo_simplexmliterator__void, ZEND_ACC_PUBLIC) + PHP_ME(ce_SimpleXMLIterator, getChildren, arginfo_simplexmliterator__void, ZEND_ACC_PUBLIC) + {NULL, NULL, NULL} +}; +/* }}} */ + +PHP_MINIT_FUNCTION(sxe) /* {{{ */ +{ + zend_class_entry **pce; + zend_class_entry sxi; + + if (zend_hash_find(CG(class_table), "simplexmlelement", sizeof("SimpleXMLElement"), (void **) &pce) == FAILURE) { + ce_SimpleXMLElement = NULL; + ce_SimpleXMLIterator = NULL; + return SUCCESS; /* SimpleXML must be initialized before */ + } + + ce_SimpleXMLElement = *pce; + + INIT_CLASS_ENTRY_EX(sxi, "SimpleXMLIterator", strlen("SimpleXMLIterator"), funcs_SimpleXMLIterator); + ce_SimpleXMLIterator = zend_register_internal_class_ex(&sxi, ce_SimpleXMLElement, NULL TSRMLS_CC); + ce_SimpleXMLIterator->create_object = ce_SimpleXMLElement->create_object; + + zend_class_implements(ce_SimpleXMLIterator TSRMLS_CC, 1, spl_ce_RecursiveIterator); + zend_class_implements(ce_SimpleXMLIterator TSRMLS_CC, 1, spl_ce_Countable); + + return SUCCESS; +} +/* }}} */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: fdm=marker + * vim: noet sw=4 ts=4 + */ diff --git a/ext/simplexml/sxe.h b/ext/simplexml/sxe.h new file mode 100644 index 0000000..5a40fef --- /dev/null +++ b/ext/simplexml/sxe.h @@ -0,0 +1,39 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Marcus Boerger <helly@php.net> | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +#ifndef SXE_H +#define SXE_H + +#include "php.h" + +extern zend_class_entry *ce_SimpleXMLIterator; + +PHP_MINIT_FUNCTION(sxe); + +#endif /* SXE_H */ + +/* + * Local Variables: + * c-basic-offset: 4 + * tab-width: 4 + * End: + * vim600: fdm=marker + * vim: noet sw=4 ts=4 + */ diff --git a/ext/simplexml/tests/000.phpt b/ext/simplexml/tests/000.phpt new file mode 100644 index 0000000..51dbe3b --- /dev/null +++ b/ext/simplexml/tests/000.phpt @@ -0,0 +1,254 @@ +--TEST-- +SimpleXML: var_dump() +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php + +$sxe = simplexml_load_file(dirname(__FILE__).'/000.xml'); + +function test($what) +{ + global $sxe; + echo "===$what\n"; + eval("var_dump(isset(\$$what));"); + eval("var_dump((bool)\$$what);"); + eval("var_dump(count(\$$what));"); + eval("var_dump(\$$what);"); +} + +test('sxe'); +test('sxe->elem1'); +test('sxe->elem1[0]'); +test('sxe->elem1[0]->elem2'); +test('sxe->elem1[0]->elem2->bla'); +if (!ini_get("unicode_semantics")) test('sxe->elem1[0]["attr1"]'); +test('sxe->elem1[0]->attr1'); +test('sxe->elem1[1]'); +test('sxe->elem1[2]'); +test('sxe->elem11'); +test('sxe->elem11->elem111'); +test('sxe->elem11->elem111->elem1111'); +test('sxe->elem22'); +test('sxe->elem22->elem222'); +test('sxe->elem22->attr22'); +test('sxe->elem22["attr22"]'); + +?> +===DONE=== +<?php exit(0); ?> +--EXPECTF-- +===sxe +bool(true) +bool(true) +int(3) +object(SimpleXMLElement)#%d (3) { + ["@attributes"]=> + array(1) { + ["id"]=> + string(3) "123" + } + ["elem1"]=> + array(2) { + [0]=> + string(36) "There is some text.Here is some more" + [1]=> + object(SimpleXMLElement)#%d (1) { + ["@attributes"]=> + array(2) { + ["attr1"]=> + string(2) "11" + ["attr2"]=> + string(2) "12" + } + } + } + ["elem11"]=> + object(SimpleXMLElement)#%d (1) { + ["elem111"]=> + object(SimpleXMLElement)#%d (1) { + ["elem1111"]=> + object(SimpleXMLElement)#%d (0) { + } + } + } +} +===sxe->elem1 +bool(true) +bool(true) +int(2) +object(SimpleXMLElement)#%d (3) { + ["@attributes"]=> + array(2) { + ["attr1"]=> + string(5) "first" + ["attr2"]=> + string(6) "second" + } + ["comment"]=> + object(SimpleXMLElement)#%d (0) { + } + ["elem2"]=> + object(SimpleXMLElement)#%d (2) { + ["@attributes"]=> + array(2) { + ["att25"]=> + string(2) "25" + ["att42"]=> + string(2) "42" + } + ["elem3"]=> + object(SimpleXMLElement)#%d (1) { + ["elem4"]=> + object(SimpleXMLElement)#%d (1) { + ["test"]=> + object(SimpleXMLElement)#%d (0) { + } + } + } + } +} +===sxe->elem1[0] +bool(true) +bool(true) +int(1) +object(SimpleXMLElement)#%d (3) { + ["@attributes"]=> + array(2) { + ["attr1"]=> + string(5) "first" + ["attr2"]=> + string(6) "second" + } + ["comment"]=> + object(SimpleXMLElement)#%d (0) { + } + ["elem2"]=> + object(SimpleXMLElement)#%d (2) { + ["@attributes"]=> + array(2) { + ["att25"]=> + string(2) "25" + ["att42"]=> + string(2) "42" + } + ["elem3"]=> + object(SimpleXMLElement)#%d (1) { + ["elem4"]=> + object(SimpleXMLElement)#%d (1) { + ["test"]=> + object(SimpleXMLElement)#%d (0) { + } + } + } + } +} +===sxe->elem1[0]->elem2 +bool(true) +bool(true) +int(1) +object(SimpleXMLElement)#%d (2) { + ["@attributes"]=> + array(2) { + ["att25"]=> + string(2) "25" + ["att42"]=> + string(2) "42" + } + ["elem3"]=> + object(SimpleXMLElement)#%d (1) { + ["elem4"]=> + object(SimpleXMLElement)#%d (1) { + ["test"]=> + object(SimpleXMLElement)#%d (0) { + } + } + } +} +===sxe->elem1[0]->elem2->bla +bool(false) +bool(false) +int(0) +object(SimpleXMLElement)#%d (0) { +} +===sxe->elem1[0]["attr1"] +bool(true) +bool(true) +int(0) +object(SimpleXMLElement)#%d (1) { + [0]=> + string(5) "first" +} +===sxe->elem1[0]->attr1 +bool(false) +bool(false) +int(0) +object(SimpleXMLElement)#%d (0) { +} +===sxe->elem1[1] +bool(true) +bool(true) +int(0) +object(SimpleXMLElement)#%d (1) { + ["@attributes"]=> + array(2) { + ["attr1"]=> + string(2) "11" + ["attr2"]=> + string(2) "12" + } +} +===sxe->elem1[2] +bool(false) +bool(false) +int(0) +NULL +===sxe->elem11 +bool(true) +bool(true) +int(1) +object(SimpleXMLElement)#%d (1) { + ["elem111"]=> + object(SimpleXMLElement)#%d (1) { + ["elem1111"]=> + object(SimpleXMLElement)#%d (0) { + } + } +} +===sxe->elem11->elem111 +bool(true) +bool(true) +int(1) +object(SimpleXMLElement)#%d (1) { + ["elem1111"]=> + object(SimpleXMLElement)#%d (0) { + } +} +===sxe->elem11->elem111->elem1111 +bool(true) +bool(true) +int(1) +object(SimpleXMLElement)#%d (0) { +} +===sxe->elem22 +bool(false) +bool(false) +int(0) +object(SimpleXMLElement)#%d (0) { +} +===sxe->elem22->elem222 +bool(false) +bool(false) +int(0) +NULL +===sxe->elem22->attr22 +bool(false) +bool(false) +int(0) +NULL +===sxe->elem22["attr22"] +bool(false) +bool(false) +int(0) +NULL +===DONE=== diff --git a/ext/simplexml/tests/000.xml b/ext/simplexml/tests/000.xml new file mode 100755 index 0000000..b0f2785 --- /dev/null +++ b/ext/simplexml/tests/000.xml @@ -0,0 +1,16 @@ +<?xml version='1.0'?> +<!DOCTYPE sxe SYSTEM "sxe.dtd" [ +<!ENTITY % incent SYSTEM "sxe.ent"> +%incent; +]> +<sxe id="123"> + <elem1 attr1='first' attr2='second'>There is some text.<!-- comment --><elem2 att25='25' att42='42'> + <elem3> + <elem4> + <?test processing instruction ?> + </elem4> + </elem3> + </elem2>Here is some more</elem1> + <elem1 attr1='11' attr2='12'/> + <elem11><elem111><elem1111/></elem111></elem11> +</sxe>
\ No newline at end of file diff --git a/ext/simplexml/tests/001.phpt b/ext/simplexml/tests/001.phpt new file mode 100644 index 0000000..0be7771 --- /dev/null +++ b/ext/simplexml/tests/001.phpt @@ -0,0 +1,43 @@ +--TEST-- +SimpleXML: Simple document +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php + +var_dump(simplexml_load_file(dirname(__FILE__).'/sxe.xml')); + +?> +===DONE=== +--EXPECTF-- +object(SimpleXMLElement)#%d (2) { + ["@attributes"]=> + array(1) { + ["id"]=> + string(5) "elem1" + } + ["elem1"]=> + object(SimpleXMLElement)#%d (3) { + ["@attributes"]=> + array(1) { + ["attr1"]=> + string(5) "first" + } + ["comment"]=> + object(SimpleXMLElement)#%d (0) { + } + ["elem2"]=> + object(SimpleXMLElement)#%d (1) { + ["elem3"]=> + object(SimpleXMLElement)#%d (1) { + ["elem4"]=> + object(SimpleXMLElement)#%d (1) { + ["test"]=> + object(SimpleXMLElement)#%d (0) { + } + } + } + } + } +} +===DONE=== diff --git a/ext/simplexml/tests/002.phpt b/ext/simplexml/tests/002.phpt new file mode 100644 index 0000000..4f1f6b6 --- /dev/null +++ b/ext/simplexml/tests/002.phpt @@ -0,0 +1,64 @@ +--TEST-- +SimpleXML: clone +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php + +$xml =<<<EOF +<?xml version='1.0'?> +<!DOCTYPE sxe SYSTEM "notfound.dtd"> +<sxe id="elem1"> + <elem1 attr1='first'> + <!-- comment --> + <elem2> + <elem3> + <elem4> + <?test processing instruction ?> + </elem4> + </elem3> + </elem2> + </elem1> +</sxe> +EOF; + +$sxe = simplexml_load_string($xml); + +$copy = clone $sxe; + +var_dump($copy); + +?> +===DONE=== +--EXPECTF-- +object(SimpleXMLElement)#%d (2) { + ["@attributes"]=> + array(1) { + ["id"]=> + string(5) "elem1" + } + ["elem1"]=> + object(SimpleXMLElement)#%d (3) { + ["@attributes"]=> + array(1) { + ["attr1"]=> + string(5) "first" + } + ["comment"]=> + object(SimpleXMLElement)#%d (0) { + } + ["elem2"]=> + object(SimpleXMLElement)#%d (1) { + ["elem3"]=> + object(SimpleXMLElement)#%d (1) { + ["elem4"]=> + object(SimpleXMLElement)#%d (1) { + ["test"]=> + object(SimpleXMLElement)#%d (0) { + } + } + } + } + } +} +===DONE=== diff --git a/ext/simplexml/tests/003.phpt b/ext/simplexml/tests/003.phpt new file mode 100644 index 0000000..105f616 --- /dev/null +++ b/ext/simplexml/tests/003.phpt @@ -0,0 +1,69 @@ +--TEST-- +SimpleXML: Entities +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php + +$xml =<<<EOF +<?xml version='1.0'?> +<!DOCTYPE sxe SYSTEM "notfound.dtd" [ +<!ENTITY included-entity "This is text included from an entity"> +]> +<sxe id="elem1"> + Plain text. + <elem1 attr1='first'> + <!-- comment --> + <elem2> + <elem3> + &included-entity; + <elem4> + <?test processing instruction ?> + </elem4> + </elem3> + </elem2> + </elem1> +</sxe> +EOF; + +var_dump(simplexml_load_string($xml)); + +?> +===DONE=== +--EXPECTF-- +object(SimpleXMLElement)#%d (2) { + ["@attributes"]=> + array(1) { + ["id"]=> + string(5) "elem1" + } + ["elem1"]=> + object(SimpleXMLElement)#%d (3) { + ["@attributes"]=> + array(1) { + ["attr1"]=> + string(5) "first" + } + ["comment"]=> + object(SimpleXMLElement)#%d (0) { + } + ["elem2"]=> + object(SimpleXMLElement)#%d (1) { + ["elem3"]=> + object(SimpleXMLElement)#%d (2) { + ["included-entity"]=> + object(SimpleXMLElement)#%d (1) { + ["included-entity"]=> + string(36) "This is text included from an entity" + } + ["elem4"]=> + object(SimpleXMLElement)#%d (1) { + ["test"]=> + object(SimpleXMLElement)#%d (0) { + } + } + } + } + } +} +===DONE=== diff --git a/ext/simplexml/tests/004.phpt b/ext/simplexml/tests/004.phpt new file mode 100644 index 0000000..21cb546 --- /dev/null +++ b/ext/simplexml/tests/004.phpt @@ -0,0 +1,68 @@ +--TEST-- +SimpleXML: CDATA +--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'> + <!-- comment --> + <elem2> + <![CDATA[CDATA block]]> + <elem3> + <elem4> + <?test processing instruction ?> + </elem4> + </elem3> + </elem2> + </elem1> +</sxe> +EOF +); + +var_dump($sxe); + +$elem1 = $sxe->elem1; +$elem2 = $elem1->elem2; +var_dump(trim((string)$elem2)); + +?> +===DONE=== +--EXPECTF-- +object(SimpleXMLElement)#%d (2) { + ["@attributes"]=> + array(1) { + ["id"]=> + string(5) "elem1" + } + ["elem1"]=> + object(SimpleXMLElement)#%d (3) { + ["@attributes"]=> + array(1) { + ["attr1"]=> + string(5) "first" + } + ["comment"]=> + object(SimpleXMLElement)#%d (0) { + } + ["elem2"]=> + object(SimpleXMLElement)#%d (1) { + ["elem3"]=> + object(SimpleXMLElement)#%d (1) { + ["elem4"]=> + object(SimpleXMLElement)#%d (1) { + ["test"]=> + object(SimpleXMLElement)#%d (0) { + } + } + } + } + } +} +string(11) "CDATA block" +===DONE=== diff --git a/ext/simplexml/tests/005.phpt b/ext/simplexml/tests/005.phpt new file mode 100644 index 0000000..1411065 --- /dev/null +++ b/ext/simplexml/tests/005.phpt @@ -0,0 +1,40 @@ +--TEST-- +SimpleXML: Text data +--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'> + <!-- comment --> + <elem2> + Here we have some text data. + <elem3> + And here some more. + <elem4> + Wow once again. + </elem4> + </elem3> + </elem2> + </elem1> +</sxe> +EOF +); + +var_dump(trim($sxe->elem1->elem2)); +var_dump(trim($sxe->elem1->elem2->elem3)); +var_dump(trim($sxe->elem1->elem2->elem3->elem4)); + +echo "---Done---\n"; + +?> +--EXPECT-- +string(28) "Here we have some text data." +string(19) "And here some more." +string(15) "Wow once again." +---Done--- diff --git a/ext/simplexml/tests/006.phpt b/ext/simplexml/tests/006.phpt new file mode 100644 index 0000000..72ad0c8 --- /dev/null +++ b/ext/simplexml/tests/006.phpt @@ -0,0 +1,80 @@ +--TEST-- +SimpleXML: foreach +--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 as $name => $data) { + var_dump($name); + var_dump(trim($data)); +} + +echo "===CLONE===\n"; + +foreach(clone $sxe as $name => $data) { + var_dump($name); + var_dump(trim($data)); +} + +echo "===ELEMENT===\n"; + +foreach($sxe->elem11 as $name => $data) { + var_dump($name); + var_dump(trim($data)); +} + +echo "===COMMENT===\n"; + +foreach($sxe->elem1 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(6) "elem11" +string(10) "Bla bla 2." +===COMMENT=== +string(5) "elem1" +string(10) "Bla bla 1." +===DONE=== diff --git a/ext/simplexml/tests/007.phpt b/ext/simplexml/tests/007.phpt new file mode 100644 index 0000000..51d7a84 --- /dev/null +++ b/ext/simplexml/tests/007.phpt @@ -0,0 +1,97 @@ +--TEST-- +SimpleXML: Attributes +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php + +$xml =<<<EOF +<?xml version='1.0'?> +<!DOCTYPE sxe SYSTEM "notfound.dtd"> +<sxe id="elem1"> + <elem1 attr1='first'> + <!-- comment --> + <elem2> + <elem3> + <elem4> + <?test processing instruction ?> + </elem4> + </elem3> + </elem2> + </elem1> +</sxe> +EOF; + +$sxe = simplexml_load_string($xml); + +echo "===Property===\n"; +var_dump($sxe->elem1); +echo "===Array===\n"; +var_dump($sxe['id']); +var_dump($sxe->elem1['attr1']); +echo "===Set===\n"; +$sxe['id'] = "Changed1"; +var_dump($sxe['id']); +$sxe->elem1['attr1'] = 12; +var_dump($sxe->elem1['attr1']); +echo "===Unset===\n"; +unset($sxe['id']); +var_dump($sxe['id']); +unset($sxe->elem1['attr1']); +var_dump($sxe->elem1['attr1']); +echo "===Misc.===\n"; +$a = 4; +var_dump($a); +$dummy = $sxe->elem1[$a]; +var_dump($a); +?> +===Done=== +--EXPECTF-- +===Property=== +object(SimpleXMLElement)#%d (3) { + ["@attributes"]=> + array(1) { + ["attr1"]=> + string(5) "first" + } + ["comment"]=> + object(SimpleXMLElement)#%d (0) { + } + ["elem2"]=> + object(SimpleXMLElement)#%d (1) { + ["elem3"]=> + object(SimpleXMLElement)#%d (1) { + ["elem4"]=> + object(SimpleXMLElement)#%d (1) { + ["test"]=> + object(SimpleXMLElement)#%d (0) { + } + } + } + } +} +===Array=== +object(SimpleXMLElement)#%d (1) { + [0]=> + string(5) "elem1" +} +object(SimpleXMLElement)#%d (1) { + [0]=> + string(5) "first" +} +===Set=== +object(SimpleXMLElement)#%d (1) { + [0]=> + string(8) "Changed1" +} +object(SimpleXMLElement)#%d (1) { + [0]=> + string(2) "12" +} +===Unset=== +NULL +NULL +===Misc.=== +int(4) +int(4) +===Done=== diff --git a/ext/simplexml/tests/008.phpt b/ext/simplexml/tests/008.phpt new file mode 100644 index 0000000..8734ba4 --- /dev/null +++ b/ext/simplexml/tests/008.phpt @@ -0,0 +1,48 @@ +--TEST-- +SimpleXML: XPath +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php + +$xml =<<<EOF +<?xml version='1.0'?> +<!DOCTYPE sxe SYSTEM "notfound.dtd"> +<sxe id="elem1"> + <elem1 attr1='first'> + <!-- comment --> + <elem2> + <elem3> + <elem4> + <?test processing instruction ?> + </elem4> + </elem3> + </elem2> + </elem1> +</sxe> +EOF; + +$sxe = simplexml_load_string($xml); + +var_dump($sxe->xpath("elem1/elem2/elem3/elem4")); +//valid expression +var_dump($sxe->xpath("***")); +//invalid expression +var_dump($sxe->xpath("**")); +?> +--EXPECTF-- +array(1) { + [0]=> + object(SimpleXMLElement)#%d (1) { + ["test"]=> + object(SimpleXMLElement)#%d (0) { + } + } +} +array(0) { +} + +Warning: SimpleXMLElement::xpath(): Invalid expression in %s on line %d + +Warning: SimpleXMLElement::xpath(): xmlXPathEval: evaluation failed in %s on line %d +bool(false) diff --git a/ext/simplexml/tests/009.phpt b/ext/simplexml/tests/009.phpt new file mode 100644 index 0000000..a76f3d1 --- /dev/null +++ b/ext/simplexml/tests/009.phpt @@ -0,0 +1,45 @@ +--TEST-- +SimpleXML: foreach +--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. + </elem11> +</sxe> +EOF +); +foreach($sxe->children() as $name=>$val) { + var_dump($name); + var_dump(get_class($val)); + var_dump(trim($val)); +} +?> +===DONE=== +--EXPECT-- +string(5) "elem1" +string(16) "SimpleXMLElement" +string(10) "Bla bla 1." +string(6) "elem11" +string(16) "SimpleXMLElement" +string(10) "Bla bla 2." +===DONE=== diff --git a/ext/simplexml/tests/009b.phpt b/ext/simplexml/tests/009b.phpt new file mode 100644 index 0000000..dba300c --- /dev/null +++ b/ext/simplexml/tests/009b.phpt @@ -0,0 +1,35 @@ +--TEST-- +SimpleXML: foreach +--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. + </elem2></elem1> + <elem11 attr2='second'>Bla bla 2.</elem11> +</sxe> +EOF +); +var_dump($sxe->children()); +?> +===DONE=== +<?php exit(0); ?> +--EXPECTF-- +object(SimpleXMLElement)#%d (3) { + ["@attributes"]=> + array(1) { + ["id"]=> + string(5) "elem1" + } + ["elem1"]=> + string(10) "Bla bla 1." + ["elem11"]=> + string(10) "Bla bla 2." +} +===DONE=== diff --git a/ext/simplexml/tests/010.phpt b/ext/simplexml/tests/010.phpt new file mode 100644 index 0000000..2677809 --- /dev/null +++ b/ext/simplexml/tests/010.phpt @@ -0,0 +1,64 @@ +--TEST-- +SimpleXML: Simple Inheritance +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php + +class simplexml_inherited extends SimpleXMLElement +{ +} + +$xml =<<<EOF +<?xml version='1.0'?> +<!DOCTYPE sxe SYSTEM "notfound.dtd"> +<sxe id="elem1"> + <elem1 attr1='first'> + <!-- comment --> + <elem2> + <elem3> + <elem4> + <?test processing instruction ?> + </elem4> + </elem3> + </elem2> + </elem1> +</sxe> +EOF; + +var_dump(simplexml_load_string($xml, 'simplexml_inherited')); + +?> +===DONE=== +--EXPECTF-- +object(simplexml_inherited)#%d (2) { + ["@attributes"]=> + array(1) { + ["id"]=> + string(5) "elem1" + } + ["elem1"]=> + object(simplexml_inherited)#%d (3) { + ["@attributes"]=> + array(1) { + ["attr1"]=> + string(5) "first" + } + ["comment"]=> + object(simplexml_inherited)#%d (0) { + } + ["elem2"]=> + object(simplexml_inherited)#%d (1) { + ["elem3"]=> + object(simplexml_inherited)#%d (1) { + ["elem4"]=> + object(simplexml_inherited)#%d (1) { + ["test"]=> + object(simplexml_inherited)#%d (0) { + } + } + } + } + } +} +===DONE=== diff --git a/ext/simplexml/tests/011.phpt b/ext/simplexml/tests/011.phpt new file mode 100644 index 0000000..74ea470 --- /dev/null +++ b/ext/simplexml/tests/011.phpt @@ -0,0 +1,47 @@ +--TEST-- +SimpleXML: echo/print +--SKIPIF-- +<?php + if (!extension_loaded('simplexml')) print 'skip'; +?> +--FILE-- +<?php + +$xml =<<<EOF +<?xml version="1.0" encoding="ISO-8859-1" ?> +<foo> + <bar>bar</bar> + <baz>baz1</baz> + <baz>baz2</baz> +</foo> +EOF; + +$sxe = simplexml_load_string($xml); + +echo "===BAR===\n"; +echo $sxe->bar; +echo "\n"; + +echo "===BAZ===\n"; +echo $sxe->baz; +echo "\n"; + +echo "===BAZ0===\n"; +echo $sxe->baz[0]; +echo "\n"; + +echo "===BAZ1===\n"; +print $sxe->baz[1]; +echo "\n"; +?> +===DONE=== +--EXPECT-- +===BAR=== +bar +===BAZ=== +baz1 +===BAZ0=== +baz1 +===BAZ1=== +baz2 +===DONE=== diff --git a/ext/simplexml/tests/012.phpt b/ext/simplexml/tests/012.phpt new file mode 100644 index 0000000..2fc9bec --- /dev/null +++ b/ext/simplexml/tests/012.phpt @@ -0,0 +1,40 @@ +--TEST-- +SimpleXML: Attribute creation +--SKIPIF-- +<?php + if (!extension_loaded('simplexml')) print 'skip'; +?> +--FILE-- +<?php + +$xml =<<<EOF +<?xml version="1.0" encoding="ISO-8859-1" ?> +<foo/> +EOF; + +$sxe = simplexml_load_string($xml); + + +$sxe[""] = "warning"; +$sxe["attr"] = "value"; + +echo $sxe->asXML(); + +$sxe["attr"] = "new value"; + +echo $sxe->asXML(); + +$sxe[] = "error"; + +__HALT_COMPILER(); +?> +===DONE=== +--EXPECTF-- + +Warning: main(): Cannot write or create unnamed attribute in %s012.php on line %d +<?xml version="1.0" encoding="ISO-8859-1"?> +<foo attr="value"/> +<?xml version="1.0" encoding="ISO-8859-1"?> +<foo attr="new value"/> + +Fatal error: main(): Cannot create unnamed attribute in %s012.php on line %d diff --git a/ext/simplexml/tests/013.phpt b/ext/simplexml/tests/013.phpt new file mode 100644 index 0000000..56c57df --- /dev/null +++ b/ext/simplexml/tests/013.phpt @@ -0,0 +1,23 @@ +--TEST-- +SimpleXML: Split text content +--SKIPIF-- +<?php + if (!extension_loaded('simplexml')) print 'skip'; +?> +--FILE-- +<?php + +$xml =<<<EOF +<?xml version="1.0" encoding="ISO-8859-1" ?> +<foo>bar<baz/>bar</foo> +EOF; + +$sxe = simplexml_load_string($xml); + +var_dump((string)$sxe); + +?> +===DONE=== +--EXPECT-- +string(6) "barbar" +===DONE=== diff --git a/ext/simplexml/tests/014.phpt b/ext/simplexml/tests/014.phpt new file mode 100644 index 0000000..d1d736e --- /dev/null +++ b/ext/simplexml/tests/014.phpt @@ -0,0 +1,60 @@ +--TEST-- +SimpleXML: adding/removing attributes (direct) +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php +$xml =<<<EOF +<people> + <person name="Joe"></person> +</people> +EOF; + +$people = simplexml_load_string($xml); +var_dump($people->person['name']); +var_dump($people->person['age']); +$person = $people->person; +$person['name'] = "XXX"; +var_dump($people->person['name']); +$people->person['age'] = 30; +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'])); +$people->person['age'] = 30; +echo "---Unsupported---\n"; +var_dump($people->person['age']); +$people->person['age'] += 5; +var_dump($people->person['age']); +?> +===DONE=== +--EXPECTF-- +object(SimpleXMLElement)#%d (1) { + [0]=> + string(3) "Joe" +} +NULL +object(SimpleXMLElement)#%d (1) { + [0]=> + string(3) "XXX" +} +object(SimpleXMLElement)#%d (1) { + [0]=> + string(2) "30" +} +---Unset:--- +---Unset?--- +NULL +bool(false) +---Unsupported--- +object(SimpleXMLElement)#%d (1) { + [0]=> + string(2) "30" +} +object(SimpleXMLElement)#%d (1) { + [0]=> + string(2) "35" +} +===DONE=== diff --git a/ext/simplexml/tests/014a.phpt b/ext/simplexml/tests/014a.phpt new file mode 100644 index 0000000..649828b --- /dev/null +++ b/ext/simplexml/tests/014a.phpt @@ -0,0 +1,56 @@ +--TEST-- +SimpleXML: adding/removing attributes (single) +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php +$xml =<<<EOF +<people> + <person name="Joe"></person> +</people> +EOF; + +$people = simplexml_load_string($xml); +var_dump($people->person[0]['name']); +var_dump($people->person[0]['age']); +$person = $people->person[0]; +$person['name'] = "XXX"; +var_dump($people->person[0]['name']); +$people->person[0]['age'] = 30; +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 "---Unsupported---\n"; +var_dump($people->person[0]['age']); +$people->person['age'] += 5; +var_dump($people->person[0]['age']); +?> +===DONE=== +--EXPECTF-- +object(SimpleXMLElement)#%d (1) { + [0]=> + string(3) "Joe" +} +NULL +object(SimpleXMLElement)#%d (1) { + [0]=> + string(3) "XXX" +} +object(SimpleXMLElement)#%d (1) { + [0]=> + string(2) "30" +} +---Unset:--- +---Unset?--- +NULL +bool(false) +---Unsupported--- +NULL +object(SimpleXMLElement)#%d (1) { + [0]=> + string(1) "5" +} +===DONE=== diff --git a/ext/simplexml/tests/014b.phpt b/ext/simplexml/tests/014b.phpt new file mode 100644 index 0000000..0343967 --- /dev/null +++ b/ext/simplexml/tests/014b.phpt @@ -0,0 +1,55 @@ +--TEST-- +SimpleXML: adding/removing attributes (second) +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php +$xml =<<<EOF +<people> + <person name="Joe"></person> + <person name="Boe"></person> +</people> +EOF; + +$people = simplexml_load_string($xml); +var_dump($people->person[0]['name']); +var_dump($people->person[1]['age']); +$person = $people->person[1]; +$person['name'] = "XXX"; +var_dump($people->person[1]['name']); +$people->person[1]['age'] = 30; +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 "---Unsupported---\n"; +$people->person[1]['age'] += 5; +var_dump($people->person[1]['age']); +?> +===DONE=== +--EXPECTF-- +object(SimpleXMLElement)#%d (1) { + [0]=> + string(3) "Joe" +} +NULL +object(SimpleXMLElement)#%d (1) { + [0]=> + string(3) "XXX" +} +object(SimpleXMLElement)#%d (1) { + [0]=> + string(2) "30" +} +---Unset:--- +---Unset?--- +NULL +bool(false) +---Unsupported--- +object(SimpleXMLElement)#%d (1) { + [0]=> + string(1) "5" +} +===DONE=== diff --git a/ext/simplexml/tests/015.phpt b/ext/simplexml/tests/015.phpt new file mode 100644 index 0000000..11e9cd5 --- /dev/null +++ b/ext/simplexml/tests/015.phpt @@ -0,0 +1,56 @@ +--TEST-- +SimpleXML: accessing singular subnode as array +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php +$xml =<<<EOF +<people> + <person name="Joe"></person> +</people> +EOF; + +$xml2 =<<<EOF +<people> + <person name="Joe"></person> + <person name="Boe"></person> +</people> +EOF; + +$people = simplexml_load_string($xml); +var_dump($people->person['name']); +var_dump($people->person[0]['name']); +//$people->person['name'] = "XXX"; +//var_dump($people->person['name']); +//var_dump($people->person[0]['name']); +//$people->person[0]['name'] = "YYY"; +//var_dump($people->person['name']); +//var_dump($people->person[0]['name']); +//unset($people->person[0]['name']); +//var_dump($people->person['name']); +//var_dump($people->person[0]['name']); +//var_dump(isset($people->person['name'])); +//var_dump(isset($people->person[0]['name'])); +$people = simplexml_load_string($xml2); +var_dump($people->person[0]['name']); +var_dump($people->person[1]['name']); +?> +===DONE=== +--EXPECTF-- +object(SimpleXMLElement)#%d (1) { + [0]=> + string(3) "Joe" +} +object(SimpleXMLElement)#%d (1) { + [0]=> + string(3) "Joe" +} +object(SimpleXMLElement)#%d (1) { + [0]=> + string(3) "Joe" +} +object(SimpleXMLElement)#%d (1) { + [0]=> + string(3) "Boe" +} +===DONE=== diff --git a/ext/simplexml/tests/016.phpt b/ext/simplexml/tests/016.phpt new file mode 100644 index 0000000..ab80a7a --- /dev/null +++ b/ext/simplexml/tests/016.phpt @@ -0,0 +1,57 @@ +--TEST-- +SimpleXML: modifying attributes of singular subnode +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php +$xml =<<<EOF +<people> + <person name="Joe"></person> +</people> +EOF; + +$people = simplexml_load_string($xml); +var_dump($people->person['name']); +$people->person['name'] = $people->person['name'] . 'Foo'; +var_dump($people->person['name']); +$people->person['name'] .= 'Bar'; +var_dump($people->person['name']); + +echo "---[0]---\n"; + +$people = simplexml_load_string($xml); +var_dump($people->person[0]['name']); +$people->person[0]['name'] = $people->person[0]['name'] . 'Foo'; +var_dump($people->person[0]['name']); +$people->person[0]['name'] .= 'Bar'; +var_dump($people->person[0]['name']); + +?> +===DONE=== +--EXPECTF-- +object(SimpleXMLElement)#%d (1) { + [0]=> + string(3) "Joe" +} +object(SimpleXMLElement)#%d (1) { + [0]=> + string(6) "JoeFoo" +} +object(SimpleXMLElement)#%d (1) { + [0]=> + string(9) "JoeFooBar" +} +---[0]--- +object(SimpleXMLElement)#%d (1) { + [0]=> + string(3) "Joe" +} +object(SimpleXMLElement)#%d (1) { + [0]=> + string(6) "JoeFoo" +} +object(SimpleXMLElement)#%d (1) { + [0]=> + string(9) "JoeFooBar" +} +===DONE=== diff --git a/ext/simplexml/tests/016a.phpt b/ext/simplexml/tests/016a.phpt new file mode 100644 index 0000000..9797e29 --- /dev/null +++ b/ext/simplexml/tests/016a.phpt @@ -0,0 +1,29 @@ +--TEST-- +SimpleXML: concatenating attributes +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php +$xml =<<<EOF +<people> + <person name="Foo"></person> +</people> +EOF; + +$people = simplexml_load_string($xml); +var_dump($people->person['name']); +$people->person['name'] .= 'Bar'; +var_dump($people->person['name']); + +?> +===DONE=== +--EXPECTF-- +object(SimpleXMLElement)#%d (1) { + [0]=> + string(3) "Foo" +} +object(SimpleXMLElement)#%d (1) { + [0]=> + string(6) "FooBar" +} +===DONE=== diff --git a/ext/simplexml/tests/017.phpt b/ext/simplexml/tests/017.phpt new file mode 100644 index 0000000..776b00c --- /dev/null +++ b/ext/simplexml/tests/017.phpt @@ -0,0 +1,86 @@ +--TEST-- +SimpleXML: iteration through subnodes +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php +$xml =<<<EOF +<people> + <person name="Joe"> + <child name="Ann" /> + <child name="Marray" /> + </person> + <person name="Boe"> + <child name="Joe" /> + <child name="Ann" /> + </person> +</people> +EOF; +$xml1 =<<<EOF +<people> + <person name="Joe"> + <child name="Ann" /> + </person> +</people> +EOF; + +function print_xml($xml) { + foreach($xml->children() as $person) { + echo "person: ".$person['name']."\n"; + foreach($person->children() as $child) { + echo " child: ".$child['name']."\n"; + } + } +} + +function print_xml2($xml) { + $persons = 2; + for ($i=0;$i<$persons;$i++) { + echo "person: ".$xml->person[$i]['name']."\n"; + $children = 2; + for ($j=0;$j<$children;$j++) { + echo " child: ".$xml->person[$i]->child[$j]['name']."\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)); +?> +===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 + 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=== diff --git a/ext/simplexml/tests/018.phpt b/ext/simplexml/tests/018.phpt new file mode 100644 index 0000000..e5c8109 --- /dev/null +++ b/ext/simplexml/tests/018.phpt @@ -0,0 +1,65 @@ +--TEST-- +SimpleXML: iteration through subnodes and attributes +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php +$xml =<<<EOF +<people> + <person name="Joe"> + Text1 + <child name="Ann" /> + Text2 + <child name="Marray" /> + Text3 + </person> + <person name="Boe"> + <child name="Joe" /> + <child name="Ann" /> + </person> +</people> +EOF; +$xml1 =<<<EOF +<people> + <person name="Joe"> + <child /> + </person> +</people> +EOF; + +function traverse_xml($pad,$xml) { + foreach($xml->children() as $name => $node) { + echo $pad."<$name"; + foreach($node->attributes() as $attr => $value) { + echo " $attr=\"$value\""; + } + echo ">\n"; + traverse_xml($pad." ",$node); + echo $pad."</$name>\n"; + } +} + +traverse_xml("",simplexml_load_string($xml)); +echo "----------\n"; +traverse_xml("",simplexml_load_string($xml1)); +echo "---Done---\n"; +?> +--EXPECT-- +<person name="Joe"> + <child name="Ann"> + </child> + <child name="Marray"> + </child> +</person> +<person name="Boe"> + <child name="Joe"> + </child> + <child name="Ann"> + </child> +</person> +---------- +<person name="Joe"> + <child> + </child> +</person> +---Done---
\ No newline at end of file diff --git a/ext/simplexml/tests/019.phpt b/ext/simplexml/tests/019.phpt new file mode 100644 index 0000000..aec74ba --- /dev/null +++ b/ext/simplexml/tests/019.phpt @@ -0,0 +1,80 @@ +--TEST-- +SimpleXML: 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(clone $sxe->children() 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/020.phpt b/ext/simplexml/tests/020.phpt new file mode 100644 index 0000000..9e91b5a --- /dev/null +++ b/ext/simplexml/tests/020.phpt @@ -0,0 +1,21 @@ +--TEST-- +SimpleXML: Attribute compared to string +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php + +$doc = simplexml_load_string('<root><name attr="foo">bar</name></root>'); +print $doc->name["attr"]; +print "\n"; +if ($doc->name["attr"] == "foo") { + print "Works\n"; +} else { + print "Error\n"; +} +?> +===DONE=== +--EXPECT-- +foo +Works +===DONE=== diff --git a/ext/simplexml/tests/021.phpt b/ext/simplexml/tests/021.phpt new file mode 100644 index 0000000..d513868 --- /dev/null +++ b/ext/simplexml/tests/021.phpt @@ -0,0 +1,25 @@ +--TEST-- +SimpleXML: Element check +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php + +$ok = 1; +$doc = simplexml_load_string('<root><exists>foo</exists></root>'); +if(!isset($doc->exists)) { + $ok *= 0; +} +if(isset($doc->doesnotexist)) { + $ok *= 0; +} +if ($ok) { + print "Works\n"; +} else { + print "Error\n"; +} +?> +===DONE=== +--EXPECT-- +Works +===DONE=== diff --git a/ext/simplexml/tests/022.phpt b/ext/simplexml/tests/022.phpt new file mode 100644 index 0000000..2af4a1d --- /dev/null +++ b/ext/simplexml/tests/022.phpt @@ -0,0 +1,62 @@ +--TEST-- +SimpleXML: Attributes inside foreach +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php + +$xml =<<<EOF +<?xml version='1.0'?> +<pres><content><file glob="slide_*.xml"/></content></pres> +EOF; + +$sxe = simplexml_load_string($xml); + +echo "===CONTENT===\n"; +var_dump($sxe->content); + +echo "===FILE===\n"; +var_dump($sxe->content->file); + +echo "===FOREACH===\n"; +foreach($sxe->content->file as $file) +{ + var_dump($file); + var_dump($file['glob']); +} + +?> +===DONE=== +--EXPECTF-- +===CONTENT=== +object(SimpleXMLElement)#%d (1) { + ["file"]=> + object(SimpleXMLElement)#%d (1) { + ["@attributes"]=> + array(1) { + ["glob"]=> + string(11) "slide_*.xml" + } + } +} +===FILE=== +object(SimpleXMLElement)#%d (1) { + ["@attributes"]=> + array(1) { + ["glob"]=> + string(11) "slide_*.xml" + } +} +===FOREACH=== +object(SimpleXMLElement)#%d (1) { + ["@attributes"]=> + array(1) { + ["glob"]=> + string(11) "slide_*.xml" + } +} +object(SimpleXMLElement)#%d (1) { + [0]=> + string(11) "slide_*.xml" +} +===DONE=== diff --git a/ext/simplexml/tests/023.phpt b/ext/simplexml/tests/023.phpt new file mode 100644 index 0000000..515a146 --- /dev/null +++ b/ext/simplexml/tests/023.phpt @@ -0,0 +1,36 @@ +--TEST-- +SimpleXML: Attributes with entities +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php + +$xml =<<<EOF +<?xml version='1.0'?> +<!DOCTYPE talks SYSTEM "nbsp.dtd" [ +<!ELEMENT root EMPTY> +<!ATTLIST root attr1 CDATA #IMPLIED> +<!ENTITY nbsp "&#x00A0;"> +]> +<root attr='foo bar baz'></root> +EOF; + +$sxe = simplexml_load_string($xml); + +var_dump($sxe); +var_dump($sxe['attr']); +?> +===DONE=== +--EXPECTF-- +object(SimpleXMLElement)#%d (1) { + ["@attributes"]=> + array(1) { + ["attr"]=> + string(%d) "foo%sbar%sbaz" + } +} +object(SimpleXMLElement)#%d (1) { + [0]=> + string(%d) "foo%sbar%sbaz" +} +===DONE=== diff --git a/ext/simplexml/tests/024.phpt b/ext/simplexml/tests/024.phpt new file mode 100644 index 0000000..9f31fd5 --- /dev/null +++ b/ext/simplexml/tests/024.phpt @@ -0,0 +1,175 @@ +--TEST-- +SimpleXML: XPath and attributes +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php + +$xml =<<<EOF +<?xml version='1.0'?> +<root> +<elem attr1='11' attr2='12' attr3='13'/> +<elem attr1='21' attr2='22' attr3='23'/> +<elem attr1='31' attr2='32' attr3='33'/> +</root> +EOF; + +$sxe = simplexml_load_string($xml); + +function test($xpath) +{ + global $sxe; + + echo "===$xpath===\n"; + var_dump($sxe->xpath($xpath)); +} + +test('elem/@attr2'); +test('//@attr2'); +test('//@*'); +test('elem[2]/@attr2'); + +?> +===DONE=== +--EXPECTF-- +===elem/@attr2=== +array(3) { + [0]=> + object(SimpleXMLElement)#%d (1) { + ["@attributes"]=> + array(1) { + ["attr2"]=> + string(2) "12" + } + } + [1]=> + object(SimpleXMLElement)#%d (1) { + ["@attributes"]=> + array(1) { + ["attr2"]=> + string(2) "22" + } + } + [2]=> + object(SimpleXMLElement)#%d (1) { + ["@attributes"]=> + array(1) { + ["attr2"]=> + string(2) "32" + } + } +} +===//@attr2=== +array(3) { + [0]=> + object(SimpleXMLElement)#%d (1) { + ["@attributes"]=> + array(1) { + ["attr2"]=> + string(2) "12" + } + } + [1]=> + object(SimpleXMLElement)#%d (1) { + ["@attributes"]=> + array(1) { + ["attr2"]=> + string(2) "22" + } + } + [2]=> + object(SimpleXMLElement)#%d (1) { + ["@attributes"]=> + array(1) { + ["attr2"]=> + string(2) "32" + } + } +} +===//@*=== +array(9) { + [0]=> + object(SimpleXMLElement)#%d (1) { + ["@attributes"]=> + array(1) { + ["attr1"]=> + string(2) "11" + } + } + [1]=> + object(SimpleXMLElement)#%d (1) { + ["@attributes"]=> + array(1) { + ["attr2"]=> + string(2) "12" + } + } + [2]=> + object(SimpleXMLElement)#%d (1) { + ["@attributes"]=> + array(1) { + ["attr3"]=> + string(2) "13" + } + } + [3]=> + object(SimpleXMLElement)#%d (1) { + ["@attributes"]=> + array(1) { + ["attr1"]=> + string(2) "21" + } + } + [4]=> + object(SimpleXMLElement)#%d (1) { + ["@attributes"]=> + array(1) { + ["attr2"]=> + string(2) "22" + } + } + [5]=> + object(SimpleXMLElement)#%d (1) { + ["@attributes"]=> + array(1) { + ["attr3"]=> + string(2) "23" + } + } + [6]=> + object(SimpleXMLElement)#%d (1) { + ["@attributes"]=> + array(1) { + ["attr1"]=> + string(2) "31" + } + } + [7]=> + object(SimpleXMLElement)#%d (1) { + ["@attributes"]=> + array(1) { + ["attr2"]=> + string(2) "32" + } + } + [8]=> + object(SimpleXMLElement)#%d (1) { + ["@attributes"]=> + array(1) { + ["attr3"]=> + string(2) "33" + } + } +} +===elem[2]/@attr2=== +array(1) { + [0]=> + object(SimpleXMLElement)#%d (1) { + ["@attributes"]=> + array(1) { + ["attr2"]=> + string(2) "22" + } + } +} +===DONE=== diff --git a/ext/simplexml/tests/025.phpt b/ext/simplexml/tests/025.phpt new file mode 100644 index 0000000..b9e3bbb --- /dev/null +++ b/ext/simplexml/tests/025.phpt @@ -0,0 +1,92 @@ +--TEST-- +SimpleXML: getting namespaces +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php + +$xml =<<<EOF +<?xml version='1.0'?> +<xhtml:html xmlns:html='http://www.w3.org/1999/xhtml' xmlns:xhtml='http://www.w3.org/TR/REC-html40'> +<xhtml:head><xhtml:title xmlns:xhtml='http://www.w3.org/TR/REC-html401'>bla</xhtml:title></xhtml:head> +<xhtml:body html:title="b"> +<html:h1>bla</html:h1> +<foo:bar xmlns:foo='foobar' xmlns:baz='foobarbaz'/> +</xhtml:body> +</xhtml:html> +EOF; + +$sxe = simplexml_load_string($xml); + +var_dump($sxe->getNamespaces()); +var_dump($sxe->getNamespaces(true)); +var_dump($sxe->getDocNamespaces()); +var_dump($sxe->getDocNamespaces(true)); + +$xml =<<<EOF +<?xml version='1.0'?> +<html xmlns='http://www.w3.org/1999/xhtml'> +<head><title xmlns='http://www.w3.org/TR/REC-html40'>bla</title></head> +</html> +EOF; + +$sxe = simplexml_load_string($xml); + +var_dump($sxe->getNamespaces()); +var_dump($sxe->getDocNamespaces()); + +$xml =<<<EOF +<?xml version='1.0'?> +<root/> +EOF; + +$sxe = simplexml_load_string($xml); + +var_dump($sxe->getNamespaces()); +var_dump($sxe->getDocNamespaces()); + +?> +===DONE=== +<?php exit(0); ?> +--EXPECTF-- +array(1) { + ["xhtml"]=> + string(31) "http://www.w3.org/TR/REC-html40" +} +array(3) { + ["xhtml"]=> + string(31) "http://www.w3.org/TR/REC-html40" + ["html"]=> + string(28) "http://www.w3.org/1999/xhtml" + ["foo"]=> + string(6) "foobar" +} +array(2) { + ["html"]=> + string(28) "http://www.w3.org/1999/xhtml" + ["xhtml"]=> + string(31) "http://www.w3.org/TR/REC-html40" +} +array(4) { + ["html"]=> + string(28) "http://www.w3.org/1999/xhtml" + ["xhtml"]=> + string(31) "http://www.w3.org/TR/REC-html40" + ["foo"]=> + string(6) "foobar" + ["baz"]=> + string(9) "foobarbaz" +} +array(1) { + [""]=> + string(28) "http://www.w3.org/1999/xhtml" +} +array(1) { + [""]=> + string(28) "http://www.w3.org/1999/xhtml" +} +array(0) { +} +array(0) { +} +===DONE=== diff --git a/ext/simplexml/tests/026.phpt b/ext/simplexml/tests/026.phpt new file mode 100644 index 0000000..d6de94b --- /dev/null +++ b/ext/simplexml/tests/026.phpt @@ -0,0 +1,40 @@ +--TEST-- +SimpleXML: getName() +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php +$xml =<<<EOF +<people> + <person>Jane</person> +</people> +EOF; + +function traverse_xml($xml, $pad = '') +{ + $name = $xml->getName(); + echo "$pad<$name"; + foreach($xml->attributes() as $attr => $value) + { + echo " $attr=\"$value\""; + } + echo ">" . trim($xml) . "\n"; + foreach($xml->children() as $node) + { + traverse_xml($node, $pad.' '); + } + echo $pad."</$name>\n"; +} + + +$people = simplexml_load_string($xml); +traverse_xml($people); + +?> +===DONE=== +--EXPECTF-- +<people> + <person>Jane + </person> +</people> +===DONE=== diff --git a/ext/simplexml/tests/027.phpt b/ext/simplexml/tests/027.phpt new file mode 100644 index 0000000..a531cca --- /dev/null +++ b/ext/simplexml/tests/027.phpt @@ -0,0 +1,83 @@ +--TEST-- +SimpleXML: Adding an elements +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php +$xml =<<<EOF +<people></people> +EOF; + +function traverse_xml($xml, $pad = '') +{ + $name = $xml->getName(); + echo "$pad<$name"; + foreach($xml->attributes() as $attr => $value) + { + echo " $attr=\"$value\""; + } + echo ">" . trim($xml) . "\n"; + foreach($xml->children() as $node) + { + traverse_xml($node, $pad.' '); + } + echo $pad."</$name>\n"; +} + + +$people = simplexml_load_string($xml); +traverse_xml($people); +$people->person = 'Joe'; +$people->person['gender'] = 'male'; +traverse_xml($people); +$people->person = 'Jane'; +traverse_xml($people); +$people->person['gender'] = 'female'; +$people->person[1] = 'Joe'; +$people->person[1]['gender'] = 'male'; +traverse_xml($people); +$people->person[3] = 'Minni-me'; +$people->person[2]['gender'] = 'male'; +traverse_xml($people); +$people->person[3]['gender'] = 'error'; +traverse_xml($people); +?> +===DONE=== +--EXPECTF-- +<people> +</people> +<people> + <person gender="male">Joe + </person> +</people> +<people> + <person gender="male">Jane + </person> +</people> +<people> + <person gender="female">Jane + </person> + <person gender="male">Joe + </person> +</people> + +Warning: main(): Cannot add element person number 3 when only 2 such elements exist in %s027.php on line %d +<people> + <person gender="female">Jane + </person> + <person gender="male">Joe + </person> + <person gender="male">Minni-me + </person> +</people> +<people> + <person gender="female">Jane + </person> + <person gender="male">Joe + </person> + <person gender="male">Minni-me + </person> + <person gender="error"> + </person> +</people> +===DONE=== diff --git a/ext/simplexml/tests/028.phpt b/ext/simplexml/tests/028.phpt new file mode 100644 index 0000000..753056b --- /dev/null +++ b/ext/simplexml/tests/028.phpt @@ -0,0 +1,42 @@ +--TEST-- +SimpleXML: Adding an elements without text +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php +$xml =<<<EOF +<people></people> +EOF; + +function traverse_xml($xml, $pad = '') +{ + $name = $xml->getName(); + echo "$pad<$name"; + foreach($xml->attributes() as $attr => $value) + { + echo " $attr=\"$value\""; + } + echo ">" . trim($xml) . "\n"; + foreach($xml->children() as $node) + { + traverse_xml($node, $pad.' '); + } + echo $pad."</$name>\n"; +} + + +$people = simplexml_load_string($xml); +traverse_xml($people); +$people->person['name'] = 'John'; +traverse_xml($people); + +?> +===DONE=== +--EXPECTF-- +<people> +</people> +<people> + <person name="John"> + </person> +</people> +===DONE=== diff --git a/ext/simplexml/tests/029.phpt b/ext/simplexml/tests/029.phpt new file mode 100644 index 0000000..86a4f30 --- /dev/null +++ b/ext/simplexml/tests/029.phpt @@ -0,0 +1,40 @@ +--TEST-- +SimpleXML: foreach and count +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php +$xml =<<<EOF +<people> + <person name="Joe"/> + <person name="John"> + <children> + <person name="Joe"/> + </children> + </person> + <person name="Jane"/> +</people> +EOF; + +$people = simplexml_load_string($xml); + +foreach($people as $person) +{ + var_dump((string)$person['name']); + var_dump(count($people)); + var_dump(count($person)); +} + +?> +===DONE=== +--EXPECTF-- +string(3) "Joe" +int(3) +int(0) +string(4) "John" +int(3) +int(1) +string(4) "Jane" +int(3) +int(0) +===DONE=== diff --git a/ext/simplexml/tests/030.phpt b/ext/simplexml/tests/030.phpt new file mode 100644 index 0000000..774a5f1 --- /dev/null +++ b/ext/simplexml/tests/030.phpt @@ -0,0 +1,44 @@ +--TEST-- +SimpleXML: isset and unset by offset +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php +$xml =<<<EOF +<root s:att1="b" att1="a" + xmlns:s="urn::test" xmlns:t="urn::test-t"> + <child1>test</child1> + <child1>test 2</child1> + <s:child3 /> +</root> +EOF; + +$sxe = simplexml_load_string($xml); + +echo $sxe->child1[0]."\n"; +echo $sxe->child1[1]."\n\n"; + +var_dump(isset($sxe->child1[1])); +unset($sxe->child1[1]); +var_dump(isset($sxe->child1[1])); +echo "\n"; + +$atts = $sxe->attributes("urn::test"); +var_dump(isset($atts[0])); +unset($atts[0]); +var_dump(isset($atts[0])); +var_dump(isset($atts[TRUE])); + +?> +===DONE=== +--EXPECT-- +test +test 2 + +bool(true) +bool(false) + +bool(true) +bool(false) +bool(false) +===DONE=== diff --git a/ext/simplexml/tests/031.phpt b/ext/simplexml/tests/031.phpt new file mode 100644 index 0000000..cd2d266 --- /dev/null +++ b/ext/simplexml/tests/031.phpt @@ -0,0 +1,57 @@ +--TEST-- +SimpleXML: addChild and addAttribute +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php +$xml =<<<EOF +<root s:att1="b" att1="a" + xmlns:s="urn::test" xmlns:t="urn::test-t"> + <child1>test</child1> + <child1>test 2</child1> + <s:child3 /> +</root> +EOF; + +$sxe = simplexml_load_string($xml); + +/* Add new attribute in a new namespace */ +$sxe->addAttribute('v:att11', 'xxx', 'urn::test-v'); + +/* Try to add attribute again -> display warning as method is for new Attr only */ +$sxe->addAttribute('v:att11', 'xxx', 'urn::test-v'); + +/* Add new attribute w/o namespace */ +$sxe->addAttribute('att2', 'no-ns'); + +$d = $sxe->attributes(); +/* Try to add element to attribute -> display warning and do not add */ +$d->addChild('m:test', 'myval', 'urn::test'); + + +/* Test adding elements in various configurations */ +$sxe->addChild('m:test1', 'myval', 'urn::test'); + +/* New namespace test */ +$n = $sxe->addChild('m:test2', 'myval', 'urn::testnew'); + +$sxe->addChild('test3', 'myval', 'urn::testnew'); +$sxe->addChild('test4', 'myval'); + +/* Does not add prefix here although name is valid (but discouraged) - change behavior? */ +$sxe->addChild('s:test5', 'myval'); + +echo $sxe->asXML(); +?> +===DONE=== +--EXPECTF-- +Warning: SimpleXMLElement::addAttribute(): Attribute already exists in %s031.php on line %d + +Warning: SimpleXMLElement::addChild(): Cannot add element to attributes in %s031.php on line %d +<?xml version="1.0"?> +<root xmlns:s="urn::test" xmlns:t="urn::test-t" xmlns:v="urn::test-v" s:att1="b" att1="a" v:att11="xxx" att2="no-ns"> + <child1>test</child1> + <child1>test 2</child1> + <s:child3/> +<s:test1>myval</s:test1><m:test2 xmlns:m="urn::testnew">myval</m:test2><test3 xmlns="urn::testnew">myval</test3><test4>myval</test4><test5>myval</test5></root> +===DONE=== diff --git a/ext/simplexml/tests/032.phpt b/ext/simplexml/tests/032.phpt new file mode 100644 index 0000000..48bc887 --- /dev/null +++ b/ext/simplexml/tests/032.phpt @@ -0,0 +1,45 @@ +--TEST-- +SimpleXML: comparing instances +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php +$xml =<<<EOF +<people> + <person name="Joe"/> + <person name="John"> + <children> + <person name="Joe"/> + </children> + </person> + <person name="Jane"/> +</people> +EOF; + +$xml1 =<<<EOF +<people> + <person name="John"> + <children> + <person name="Joe"/> + </children> + </person> + <person name="Jane"/> +</people> +EOF; + + +$people = simplexml_load_string($xml); +$people1 = simplexml_load_string($xml); +$people2 = simplexml_load_string($xml1); + +var_dump($people1 == $people); +var_dump($people2 == $people); +var_dump($people2 == $people1); + +?> +===DONE=== +--EXPECTF-- +bool(false) +bool(false) +bool(false) +===DONE=== diff --git a/ext/simplexml/tests/033.phpt b/ext/simplexml/tests/033.phpt new file mode 100644 index 0000000..ba01b21 --- /dev/null +++ b/ext/simplexml/tests/033.phpt @@ -0,0 +1,137 @@ +--TEST-- +SimpleXML: casting instances +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php + +$xml =<<<EOF +<people> +test + <person name="Joe"/> + <person name="John"> + <children> + <person name="Joe"/> + </children> + </person> + <person name="Jane"/> +</people> +EOF; + +$foo = simplexml_load_string( "<foo />" ); +$people = simplexml_load_string($xml); + +var_dump((bool)$foo); +var_dump((bool)$people); +var_dump((int)$foo); +var_dump((int)$people); +var_dump((double)$foo); +var_dump((double)$people); +var_dump((string)$foo); +var_dump((string)$people); +var_dump((array)$foo); +var_dump((array)$people); +var_dump((object)$foo); +var_dump((object)$people); + +?> +===DONE=== +--EXPECTF-- +bool(false) +bool(true) +int(0) +int(0) +float(0) +float(0) +string(0) "" +string(15) " +test + + + +" +array(0) { +} +array(1) { + ["person"]=> + array(3) { + [0]=> + object(SimpleXMLElement)#%d (1) { + ["@attributes"]=> + array(1) { + ["name"]=> + string(3) "Joe" + } + } + [1]=> + object(SimpleXMLElement)#%d (2) { + ["@attributes"]=> + array(1) { + ["name"]=> + string(4) "John" + } + ["children"]=> + object(SimpleXMLElement)#%d (1) { + ["person"]=> + object(SimpleXMLElement)#%d (1) { + ["@attributes"]=> + array(1) { + ["name"]=> + string(3) "Joe" + } + } + } + } + [2]=> + object(SimpleXMLElement)#%d (1) { + ["@attributes"]=> + array(1) { + ["name"]=> + string(4) "Jane" + } + } + } +} +object(SimpleXMLElement)#%d (0) { +} +object(SimpleXMLElement)#%d (1) { + ["person"]=> + array(3) { + [0]=> + object(SimpleXMLElement)#%d (1) { + ["@attributes"]=> + array(1) { + ["name"]=> + string(3) "Joe" + } + } + [1]=> + object(SimpleXMLElement)#%d (2) { + ["@attributes"]=> + array(1) { + ["name"]=> + string(4) "John" + } + ["children"]=> + object(SimpleXMLElement)#%d (1) { + ["person"]=> + object(SimpleXMLElement)#%d (1) { + ["@attributes"]=> + array(1) { + ["name"]=> + string(3) "Joe" + } + } + } + } + [2]=> + object(SimpleXMLElement)#%d (1) { + ["@attributes"]=> + array(1) { + ["name"]=> + string(4) "Jane" + } + } + } +} +===DONE=== diff --git a/ext/simplexml/tests/034.phpt b/ext/simplexml/tests/034.phpt new file mode 100644 index 0000000..8610f70 --- /dev/null +++ b/ext/simplexml/tests/034.phpt @@ -0,0 +1,24 @@ +--TEST-- +SimpleXML: cast to array +--FAIL-- +Length of cast array does not match expected length +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php +$string = '<?xml version="1.0"?> +<foo><bar> + <p>Blah 1</p> + <p>Blah 2</p> + <p>Blah 3</p> + <tt>Blah 4</tt> +</bar></foo> +'; +$foo = simplexml_load_string($string); +$p = $foo->bar->p; +echo count($p); +$p = (array)$foo->bar->p; +echo count($p); +?> +--EXPECTF-- +33 diff --git a/ext/simplexml/tests/035.phpt b/ext/simplexml/tests/035.phpt new file mode 100644 index 0000000..2162c86 --- /dev/null +++ b/ext/simplexml/tests/035.phpt @@ -0,0 +1,26 @@ +--TEST-- +SimpleXML: __toString +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php +$string = '<?xml version="1.0"?> +<foo><bar> + <p>Blah 1</p> + <p>Blah 2</p> + <p>Blah 3</p> + <tt>Blah 4</tt> +</bar></foo> +'; +$foo = simplexml_load_string($string); +$p = $foo->bar->p; +echo $p."\n"; +echo $p->__toString()."\n"; +echo $p."\n"; +?> +==Done== +--EXPECT-- +Blah 1 +Blah 1 +Blah 1 +==Done== diff --git a/ext/simplexml/tests/036.phpt b/ext/simplexml/tests/036.phpt new file mode 100644 index 0000000..24bfe60 --- /dev/null +++ b/ext/simplexml/tests/036.phpt @@ -0,0 +1,22 @@ +--TEST-- +SimpleXML: overriden count() method +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php +class SXE extends SimpleXmlElement { + public function count() { + echo "Called Count!\n"; + return parent::count(); + } +} + +$str = '<xml><c>asdf</c><c>ghjk</c></xml>'; +$sxe = new SXE($str); +var_dump(count($sxe)); +?> +==Done== +--EXPECT-- +Called Count! +int(2) +==Done== diff --git a/ext/simplexml/tests/SimpleXMLElement_addAttribute_basic.phpt b/ext/simplexml/tests/SimpleXMLElement_addAttribute_basic.phpt new file mode 100644 index 0000000..15c81b2 --- /dev/null +++ b/ext/simplexml/tests/SimpleXMLElement_addAttribute_basic.phpt @@ -0,0 +1,21 @@ +--TEST-- +SimpleXMLElement->addAttribute() +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) die("skip"); ?> +--FILE-- +<?php + $simple = simplexml_load_file(dirname(__FILE__)."/book.xml"); + $simple->addAttribute('type','novels'); + + var_dump($simple->attributes()); + echo "Done"; +?> +--EXPECTF-- +object(SimpleXMLElement)#2 (1) { + ["@attributes"]=> + array(1) { + ["type"]=> + string(6) "novels" + } +} +Done
\ No newline at end of file diff --git a/ext/simplexml/tests/SimpleXMLElement_addAttribute_required_attribute_name.phpt b/ext/simplexml/tests/SimpleXMLElement_addAttribute_required_attribute_name.phpt new file mode 100644 index 0000000..22ea448 --- /dev/null +++ b/ext/simplexml/tests/SimpleXMLElement_addAttribute_required_attribute_name.phpt @@ -0,0 +1,18 @@ +--TEST-- +SimpleXMLElement: Test to ensure that the required attribute name correctly is giving a warning +--CREDITS-- +Havard Eide <nucleuz@gmail.com> +#PHPTestFest2009 Norway 2009-06-09 \o/ +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) { echo "skip extension not available"; } ?> +--FILE-- +<?php +$a = new SimpleXMLElement("<php>testfest</php>"); +$a->addAttribute( "", "" ); +echo $a->asXML(); +?> +--EXPECTF-- +Warning: SimpleXMLElement::addAttribute(): Attribute name is required in %s on line %d +<?xml version="1.0"?> +<php>testfest</php> + diff --git a/ext/simplexml/tests/book.xml b/ext/simplexml/tests/book.xml new file mode 100644 index 0000000..ea40508 --- /dev/null +++ b/ext/simplexml/tests/book.xml @@ -0,0 +1,10 @@ +<books> + <book> + <title>The Grapes of Wrath</title> + <author>John Steinbeck</author> + </book> + <book> + <title>The Pearl</title> + <author>John Steinbeck</author> + </book> +</books> diff --git a/ext/simplexml/tests/bug24392.phpt b/ext/simplexml/tests/bug24392.phpt new file mode 100644 index 0000000..0a462e5 --- /dev/null +++ b/ext/simplexml/tests/bug24392.phpt @@ -0,0 +1,22 @@ +--TEST-- +Bug #24392 (empty namespaces causing confusion) +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip simplexml extension is not loaded"; ?> +--FILE-- +<?php +$s = simplexml_load_file(dirname(__FILE__).'/bug24392.xml'); +foreach ($s->item as $item) { + echo $item->title . "\n"; +} +?> +--EXPECT-- +EU Parliament to Vote on New Patent Rules +Most Powerful Amateur Rocket in Canada +GF FX 5900 Ultra vs. ATi Radeon 9800 Pro +PHP 5 Beta 1 +Engaging with the OSS Community +Pure Math, Pure Joy +Windows Tech Writer Looks at Linux +US Cell Phone Users Discover SMS Spam +Verizon Sues Nextel For Espionage +Introduction to Debian diff --git a/ext/simplexml/tests/bug24392.xml b/ext/simplexml/tests/bug24392.xml new file mode 100644 index 0000000..d669f1d --- /dev/null +++ b/ext/simplexml/tests/bug24392.xml @@ -0,0 +1,76 @@ +<?xml version="1.0"?> + +<rdf:RDF +xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" +xmlns="http://my.netscape.com/rdf/simple/0.9/"> + +<channel> +<title>Slashdot</title> +<link>http://slashdot.org/</link> +<description>News for nerds, stuff that matters</description> +</channel> + +<image> +<title>Slashdot</title> +<url>http://images.slashdot.org/topics/topicslashdot.gif</url> +<link>http://slashdot.org/</link> +</image> + +<item> +<title>EU Parliament to Vote on New Patent Rules</title> +<link>http://slashdot.org/article.pl?sid=03/06/30/002211</link> +</item> + +<item> +<title>Most Powerful Amateur Rocket in Canada</title> +<link>http://slashdot.org/article.pl?sid=03/06/29/2121211</link> +</item> + +<item> +<title>GF FX 5900 Ultra vs. ATi Radeon 9800 Pro</title> +<link>http://slashdot.org/article.pl?sid=03/06/29/202218</link> +</item> + +<item> +<title>PHP 5 Beta 1</title> +<link>http://slashdot.org/article.pl?sid=03/06/29/1957253</link> +</item> + +<item> +<title>Engaging with the OSS Community</title> +<link>http://slashdot.org/article.pl?sid=03/06/29/1913235</link> +</item> + +<item> +<title>Pure Math, Pure Joy</title> +<link>http://slashdot.org/article.pl?sid=03/06/29/183258</link> +</item> + +<item> +<title>Windows Tech Writer Looks at Linux</title> +<link>http://slashdot.org/article.pl?sid=03/06/29/1554201</link> +</item> + +<item> +<title>US Cell Phone Users Discover SMS Spam</title> +<link>http://slashdot.org/article.pl?sid=03/06/29/1542249</link> +</item> + +<item> +<title>Verizon Sues Nextel For Espionage</title> +<link>http://slashdot.org/article.pl?sid=03/06/29/1443230</link> +</item> + +<item> +<title>Introduction to Debian</title> +<link>http://slashdot.org/article.pl?sid=03/06/29/1424213</link> +</item> + +<textinput> +<title>Search Slashdot</title> +<description>Search Slashdot stories</description> +<name>query</name> +<link>http://slashdot.org/search.pl</link> +</textinput> + +</rdf:RDF>
\ No newline at end of file diff --git a/ext/simplexml/tests/bug25756.xsd b/ext/simplexml/tests/bug25756.xsd new file mode 100644 index 0000000..427b7a1 --- /dev/null +++ b/ext/simplexml/tests/bug25756.xsd @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> + <xsd:element name="foo" type="foo-type" /> + <xsd:complexType name="item-type"> + <xsd:all> + <xsd:element name="product-name" type="xsd:string" + minOccurs="1" maxOccurs="1"/> + <xsd:element name="quantity" type="xsd:decimal" + minOccurs="1" maxOccurs="1"/> + </xsd:all> + </xsd:complexType> + <xsd:complexType name="foo-type"> + <xsd:sequence> + <xsd:element name="items" minoccurs="1" maxOccurs="1"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="item" type="item-type" + minOccurs="0" maxOccurs="unbounded" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + </xsd:sequence> + </xsd:complexType> +</xsd:schema> diff --git a/ext/simplexml/tests/bug25756_1.xml b/ext/simplexml/tests/bug25756_1.xml new file mode 100644 index 0000000..33ab30b --- /dev/null +++ b/ext/simplexml/tests/bug25756_1.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<foo> + <items> + <item> + <product-name>abc</product-name> + <quantity>123</quantity> + </item> + <item> + <product-name>def</product-name> + <quantity>456</quantity> + </item> + </items> +</foo> diff --git a/ext/simplexml/tests/bug25756_2.xml b/ext/simplexml/tests/bug25756_2.xml new file mode 100644 index 0000000..53037ef --- /dev/null +++ b/ext/simplexml/tests/bug25756_2.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<foo> + <items> + <item> + <product-name>abc</product-name> + <quantity>abc</quantity> + </item> + <item> + <product-name>abc</product-name> + <quantity>123</quantity> + </item> + </items> +</foo> diff --git a/ext/simplexml/tests/bug26976.phpt b/ext/simplexml/tests/bug26976.phpt new file mode 100644 index 0000000..657c229 --- /dev/null +++ b/ext/simplexml/tests/bug26976.phpt @@ -0,0 +1,28 @@ +--TEST-- +Bug #26976 (Can not access array elements using array indices) +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip simplexml extension is not loaded"; ?> +--FILE-- +<?php + +$root = simplexml_load_string( +'<?xml version="1.0"?> +<root> + <child>a</child> + <child>b</child> + <child>c</child> + <child>d</child> +</root> +'); + +echo $root->child[0], "\n"; +echo $root->child[1], "\n"; +echo $root->child[2], "\n"; +echo $root->child[3], "\n"; + +?> +--EXPECT-- +a +b +c +d diff --git a/ext/simplexml/tests/bug27010.phpt b/ext/simplexml/tests/bug27010.phpt new file mode 100644 index 0000000..364ca46 --- /dev/null +++ b/ext/simplexml/tests/bug27010.phpt @@ -0,0 +1,34 @@ +--TEST-- +Bug #27010 (segfault and node text not displayed when returned from children()) +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php + +$xml=<<<EOF +<drinks xmlns:hot="http://www.example.com/hot"> + <hot:drink><hot:name>Coffee</hot:name></hot:drink> + <hot:drink><hot:name>Tea</hot:name></hot:drink> + <drink><name>Cola</name></drink> + <drink><name>Juice</name></drink> +</drinks> +EOF; + +$sxe = simplexml_load_string($xml); + +foreach ($sxe as $element_name => $element) { + print "$element_name is $element->name\n"; +} + +foreach ($sxe->children('http://www.example.com/hot') as $element_name => $element) { + print "$element_name is $element->name\n"; +} + +?> +===DONE=== +--EXPECT-- +drink is Cola +drink is Juice +drink is Coffee +drink is Tea +===DONE=== diff --git a/ext/simplexml/tests/bug35785.phpt b/ext/simplexml/tests/bug35785.phpt new file mode 100644 index 0000000..0e03f07 --- /dev/null +++ b/ext/simplexml/tests/bug35785.phpt @@ -0,0 +1,30 @@ +--TEST-- +Bug #35785 (SimpleXML memory read error) +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php + +$xml = simplexml_load_string("<root></root>"); +$xml->bla->posts->name = "FooBar"; +echo $xml->asXML(); +$xml = simplexml_load_string("<root></root>"); +$count = count($xml->bla->posts); +var_dump($count); +$xml->bla->posts[$count]->name = "FooBar"; +echo $xml->asXML(); +$xml = simplexml_load_string("<root></root>"); +$xml->bla->posts[]->name = "FooBar"; +echo $xml->asXML(); +?> +===DONE=== +<?php exit(0); __halt_compiler(); ?> +--EXPECTF-- +<?xml version="1.0"?> +<root><bla><posts><name>FooBar</name></posts></bla></root> +int(0) +<?xml version="1.0"?> +<root><bla><posts><name>FooBar</name></posts></bla></root> +<?xml version="1.0"?> +<root><bla><posts><name>FooBar</name></posts></bla></root> +===DONE=== diff --git a/ext/simplexml/tests/bug36611.phpt b/ext/simplexml/tests/bug36611.phpt new file mode 100644 index 0000000..fdcfd47 --- /dev/null +++ b/ext/simplexml/tests/bug36611.phpt @@ -0,0 +1,30 @@ +--TEST-- +Bug #36611 (assignment to SimpleXML object attribute changes argument type to string) +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php + +$xml_str = <<<EOD +<?xml version="1.0" encoding="ISO-8859-1" ?> +<c_fpobel > + <pos > + <pos/> + </pos> +</c_fpobel> +EOD; + +$xml = simplexml_load_string ($xml_str) ; + +$val = 1; + +var_dump($val); +$zml->pos["act_idx"] = $val; +var_dump($val) ; + +?> +===DONE=== +--EXPECT-- +int(1) +int(1) +===DONE=== diff --git a/ext/simplexml/tests/bug37076.phpt b/ext/simplexml/tests/bug37076.phpt new file mode 100644 index 0000000..c7f19b3 --- /dev/null +++ b/ext/simplexml/tests/bug37076.phpt @@ -0,0 +1,16 @@ +--TEST-- +Bug #37076 (SimpleXML ignores .=) +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php +$xml = simplexml_load_string("<root><foo /></root>"); +$xml->foo = "foo"; +$xml->foo .= "bar"; +print $xml->asXML(); +?> +===DONE=== +--EXPECT-- +<?xml version="1.0"?> +<root><foo>foobar</foo></root> +===DONE=== diff --git a/ext/simplexml/tests/bug37076_1.phpt b/ext/simplexml/tests/bug37076_1.phpt new file mode 100644 index 0000000..d4f4e03 --- /dev/null +++ b/ext/simplexml/tests/bug37076_1.phpt @@ -0,0 +1,18 @@ +--TEST-- +Bug #37076 (SimpleXML ignores .=) (appending to unnamed attribute) +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php +$xml = simplexml_load_string("<root><foo /></root>"); +$xml->{""} .= "bar"; +print $xml->asXML(); +?> +===DONE=== +--EXPECTF-- +Warning: main(): Cannot write or create unnamed element in %s on line %d + +Warning: main(): Cannot write or create unnamed element in %s on line %d +<?xml version="1.0"?> +<root><foo/></root> +===DONE=== diff --git a/ext/simplexml/tests/bug37386.phpt b/ext/simplexml/tests/bug37386.phpt new file mode 100644 index 0000000..cf86906 --- /dev/null +++ b/ext/simplexml/tests/bug37386.phpt @@ -0,0 +1,25 @@ +--TEST-- +Bug #39760 (autocreating element doesn't assign value to first node) +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip simplexml extension is not loaded"; ?> +--FILE-- +<?php + +$sx1 = new SimpleXMLElement((binary)"<root />"); + +$sx1->node[0] = 'node1'; +$sx1->node[1] = 'node2'; + +print $sx1->asXML()."\n"; +$node = $sx1->node[0]; +$node[0] = 'New Value'; + +print $sx1->asXML(); + +?> +--EXPECTF-- +<?xml version="1.0"?> +<root><node>node1</node><node>node2</node></root> + +<?xml version="1.0"?> +<root><node>New Value</node><node>node2</node></root> diff --git a/ext/simplexml/tests/bug37565.phpt b/ext/simplexml/tests/bug37565.phpt new file mode 100644 index 0000000..c1e5104 --- /dev/null +++ b/ext/simplexml/tests/bug37565.phpt @@ -0,0 +1,31 @@ +--TEST-- +Bug #37565 (Using reflection::export with simplexml causing a crash) +--SKIPIF-- +<?php if (!extension_loaded("simplexml") || !extension_loaded('reflection')) print "skip"; ?> +--FILE-- +<?php + +function my_error_handler($errno, $errstr, $errfile, $errline) { + echo "Error: $errstr\n"; +} + +set_error_handler('my_error_handler'); + +class Setting extends ReflectionObject +{ +} + +Reflection::export(simplexml_load_string('<test/>', 'Setting')); + +Reflection::export(simplexml_load_file('data:,<test/>', 'Setting')); + +?> +===DONE=== +--EXPECTF-- +Error: simplexml_load_string() expects parameter 2 to be a class name derived from SimpleXMLElement, 'Setting' given +Error: Argument 1 passed to Reflection::export() must implement interface Reflector, null given +Error: Reflection::export() expects parameter 1 to be Reflector, null given +Error: simplexml_load_file() expects parameter 2 to be a class name derived from SimpleXMLElement, 'Setting' given +Error: Argument 1 passed to Reflection::export() must implement interface Reflector, null given +Error: Reflection::export() expects parameter 1 to be Reflector, null given +===DONE=== diff --git a/ext/simplexml/tests/bug38347.phpt b/ext/simplexml/tests/bug38347.phpt new file mode 100644 index 0000000..0ea7b5d --- /dev/null +++ b/ext/simplexml/tests/bug38347.phpt @@ -0,0 +1,28 @@ +--TEST-- +Bug #38347 (Segmentation fault when using foreach with an unknown/empty SimpleXMLElement) +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php + +function iterate($xml) +{ + print_r($xml); + foreach ($xml->item as $item) { + echo "This code will crash!"; + } +} + +$xmlstr = "<xml><item>Item 1</item><item>Item 2</item></xml>"; +$xml = simplexml_load_string($xmlstr); +iterate($xml->unknown); + +echo "Done\n"; +?> +--EXPECTF-- +SimpleXMLElement Object +( +) + +Warning: Invalid argument supplied for foreach() in %sbug38347.php on line 6 +Done diff --git a/ext/simplexml/tests/bug38354.phpt b/ext/simplexml/tests/bug38354.phpt new file mode 100644 index 0000000..d2fcde1 --- /dev/null +++ b/ext/simplexml/tests/bug38354.phpt @@ -0,0 +1,28 @@ +--TEST-- +Bug #38354 (Unwanted reformatting of XML when using AsXML) +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php + +$xml = simplexml_load_string( +'<code> + <a href="javascript:alert(\'1\');"><strong>Item Two</strong></a> +</code>' +); + +foreach ($xml->xpath("//*") as $element) { + var_dump($element->asXML()); +} + +echo "Done\n"; +?> +--EXPECTF-- +string(101) "<?xml version="1.0"?> +<code> + <a href="javascript:alert('1');"><strong>Item Two</strong></a> +</code> +" +string(62) "<a href="javascript:alert('1');"><strong>Item Two</strong></a>" +string(25) "<strong>Item Two</strong>" +Done diff --git a/ext/simplexml/tests/bug38406.phpt b/ext/simplexml/tests/bug38406.phpt new file mode 100644 index 0000000..f439e33 --- /dev/null +++ b/ext/simplexml/tests/bug38406.phpt @@ -0,0 +1,33 @@ +--TEST-- +Bug #38406 (crash when assigning objects to SimpleXML attributes) +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php + +$item = new SimpleXMLElement(b'<something />'); +$item->attribute = b'something'; +var_dump($item->attribute); + +$item->otherAttribute = $item->attribute; +var_dump($item->otherAttribute); + +$a = array(); +$item->$a = new stdclass; + +echo "Done\n"; +?> +--EXPECTF-- +object(SimpleXMLElement)#%d (1) { + [0]=> + string(9) "something" +} +object(SimpleXMLElement)#%d (1) { + [0]=> + string(9) "something" +} + +Notice: Array to string conversion in %s on line %d + +Warning: It is not yet possible to assign complex types to properties in %s on line %d +Done diff --git a/ext/simplexml/tests/bug38424.phpt b/ext/simplexml/tests/bug38424.phpt new file mode 100644 index 0000000..baab45f --- /dev/null +++ b/ext/simplexml/tests/bug38424.phpt @@ -0,0 +1,26 @@ +--TEST-- +Bug #38424 (Different attribute assignment if new or exists) +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php + +$xml = simplexml_load_string('<xml></xml>'); + +$str = "abc & def" ; + +$xml["a1"] = "" ; +$xml["a1"] = htmlspecialchars($str,ENT_NOQUOTES) ; + +$xml["a2"] = htmlspecialchars($str,ENT_NOQUOTES) ; + +$xml["a3"] = "" ; +$xml["a3"] = $str ; + +$xml["a4"] = $str ; + +echo $xml->asXML(); +?> +--EXPECT-- +<?xml version="1.0"?> +<xml a1="abc &amp; def" a2="abc &amp; def" a3="abc & def" a4="abc & def"/> diff --git a/ext/simplexml/tests/bug39662.phpt b/ext/simplexml/tests/bug39662.phpt new file mode 100644 index 0000000..ae15f2e --- /dev/null +++ b/ext/simplexml/tests/bug39662.phpt @@ -0,0 +1,37 @@ +--TEST-- +Bug #39662 (Segfault when calling asXML() of a cloned SimpleXMLElement) +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip simplexml extension is not loaded"; ?> +--FILE-- +<?php + +$xml = '<?xml version="1.0" encoding="utf-8" ?> +<test> + +</test>'; + +$root = simplexml_load_string($xml); +$clone = clone $root; +var_dump($root); +var_dump($clone); +var_dump($clone->asXML()); + +echo "Done\n"; +?> +--EXPECTF-- +object(SimpleXMLElement)#%d (1) { + [0]=> + string(2) " + +" +} +object(SimpleXMLElement)#%d (1) { + [0]=> + string(2) " + +" +} +string(15) "<test> + +</test>" +Done diff --git a/ext/simplexml/tests/bug39760.phpt b/ext/simplexml/tests/bug39760.phpt new file mode 100644 index 0000000..e781765 --- /dev/null +++ b/ext/simplexml/tests/bug39760.phpt @@ -0,0 +1,40 @@ +--TEST-- +Bug #39760 (cloning fails on nested SimpleXML-Object) +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip simplexml extension is not loaded"; ?> +--FILE-- +<?php + +$xml = '<?xml version="1.0" ?> +<test> + <level1> + <level2a>text1</level2a> + <level2b>text2</level2b> + </level1> +</test>'; +$test = simplexml_load_string($xml); + +var_dump($test->level1->level2a); + +$test2 = clone $test; +var_dump($test2->level1->level2a); + +$test3 = clone $test->level1->level2a; +var_dump($test3); + +echo "Done\n"; +?> +--EXPECTF-- +object(SimpleXMLElement)#%d (1) { + [0]=> + string(5) "text1" +} +object(SimpleXMLElement)#%d (1) { + [0]=> + string(5) "text1" +} +object(SimpleXMLElement)#%d (1) { + [0]=> + string(5) "text1" +} +Done diff --git a/ext/simplexml/tests/bug40451.phpt b/ext/simplexml/tests/bug40451.phpt new file mode 100644 index 0000000..afd78c7 --- /dev/null +++ b/ext/simplexml/tests/bug40451.phpt @@ -0,0 +1,24 @@ +--TEST-- +Bug #40451 (addAttribute() may crash when used with non-existent child node) +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php + +$string = <<<XML +<?xml version="1.0"?> + <Host enable="true"> + <Name>host.server.com</Name> + </Host> +XML; + +$xml = simplexml_load_string($string); + +$add = $xml->addChild('Host'); +$add->Host->addAttribute('enable', 'true'); + +?> +===DONE=== +--EXPECTF-- +Warning: SimpleXMLElement::addAttribute(): Unable to locate parent Element in %s on line %d +===DONE=== diff --git a/ext/simplexml/tests/bug41175.phpt b/ext/simplexml/tests/bug41175.phpt new file mode 100644 index 0000000..db03da9 --- /dev/null +++ b/ext/simplexml/tests/bug41175.phpt @@ -0,0 +1,18 @@ +--TEST-- +Bug #41175 (addAttribute() fails to add an attribute with an empty value) +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php + +$xml = new SimpleXmlElement("<img></img>"); +$xml->addAttribute("src", "foo"); +$xml->addAttribute("alt", ""); +echo $xml->asXML(); + +?> +===DONE=== +--EXPECT-- +<?xml version="1.0"?> +<img src="foo" alt=""/> +===DONE===
\ No newline at end of file diff --git a/ext/simplexml/tests/bug41582.phpt b/ext/simplexml/tests/bug41582.phpt new file mode 100644 index 0000000..8733810 --- /dev/null +++ b/ext/simplexml/tests/bug41582.phpt @@ -0,0 +1,20 @@ +--TEST-- +Bug #41582 (SimpleXML crashes when accessing newly created element) +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php + +$xml = new SimpleXMLElement('<?xml version="1.0" standalone="yes"?> +<collection></collection>'); + +$xml->movie[]->characters->character[0]->name = 'Miss Coder'; + +echo($xml->asXml()); + +?> +===DONE=== +--EXPECT-- +<?xml version="1.0" standalone="yes"?> +<collection><movie><characters><character><name>Miss Coder</name></character></characters></movie></collection> +===DONE=== diff --git a/ext/simplexml/tests/bug41861.phpt b/ext/simplexml/tests/bug41861.phpt new file mode 100644 index 0000000..607d301 --- /dev/null +++ b/ext/simplexml/tests/bug41861.phpt @@ -0,0 +1,42 @@ +--TEST-- +Bug #41861 (getNamespaces() returns the namespaces of a node's siblings) +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php + +$xml = simplexml_load_string('<root> + <first_node_no_ns /> + <ns1:node1 xmlns:ns1="#ns1" /> + <ns2:node2 xmlns:ns2="#ns2" /> + <ns3:node3 xmlns:ns3="#ns3" /> + <last_node_no_ns /> +</root>'); + +$name = $xml->getName(); +$namespaces = $xml->getNamespaces(True); +echo "root(recursive): '$name' -- namespaces: ", implode(', ', $namespaces), "\n"; +$namespaces = $xml->getNamespaces(False); +echo "root(non-recursive): '$name' -- namespaces: ", implode(', ', $namespaces), "\n"; + +foreach (array(null, '#ns1', '#ns2', '#ns3') as $ns) +{ + foreach ($xml->children($ns) as $child) + { + $name = $child->getName(); + $namespaces = $child->getNamespaces(false); + + echo "children($ns): '$name' -- namespaces: ", implode(', ', $namespaces), "\n"; + } +} +?> +===DONE=== +--EXPECT-- +root(recursive): 'root' -- namespaces: #ns1, #ns2, #ns3 +root(non-recursive): 'root' -- namespaces: +children(): 'first_node_no_ns' -- namespaces: +children(): 'last_node_no_ns' -- namespaces: +children(#ns1): 'node1' -- namespaces: #ns1 +children(#ns2): 'node2' -- namespaces: #ns2 +children(#ns3): 'node3' -- namespaces: #ns3 +===DONE=== diff --git a/ext/simplexml/tests/bug41867.phpt b/ext/simplexml/tests/bug41867.phpt new file mode 100644 index 0000000..33e2de9 --- /dev/null +++ b/ext/simplexml/tests/bug41867.phpt @@ -0,0 +1,18 @@ +--TEST-- +Bug #41867 (getName is broken) +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php + +$a = simplexml_load_string("<a><b><c/></b></a>"); +echo $a->getName()."\n"; +echo $a->b->getName()."\n"; +echo $a->b->c->getName()."\n"; +?> +===DONE=== +--EXPECT-- +a +b +c +===DONE=== diff --git a/ext/simplexml/tests/bug41947.phpt b/ext/simplexml/tests/bug41947.phpt new file mode 100644 index 0000000..0b974ce --- /dev/null +++ b/ext/simplexml/tests/bug41947.phpt @@ -0,0 +1,18 @@ +--TEST-- +Bug #41947 (addChild incorrectly registers empty strings as namespaces) +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php +$xml = simplexml_load_string('<?xml version="1.0" encoding="utf-8"?><root xmlns:myns="http://myns" />'); +$grandchild = $xml->addChild('child', null, 'http://myns')->addChild('grandchild', 'hello', ''); + +$gchild = $xml->xpath("//grandchild"); +if (count($gchild) > 0) { + echo $gchild[0]."\n"; +} +?> +===DONE=== +--EXPECT-- +hello +===DONE=== diff --git a/ext/simplexml/tests/bug42259.phpt b/ext/simplexml/tests/bug42259.phpt new file mode 100644 index 0000000..19c02a5 --- /dev/null +++ b/ext/simplexml/tests/bug42259.phpt @@ -0,0 +1,49 @@ +--TEST-- +Bug #42259 (SimpleXMLIterator loses ancestry) +--SKIPIF-- +<?php +if (!extension_loaded('simplexml')) print 'skip'; +if (!extension_loaded("libxml")) print "skip LibXML not present"; +?> +--FILE-- +<?php +$xml =<<<EOF +<xml> + <fieldset1> + <field1/> + <field2/> + </fieldset1> + <fieldset2> + <options> + <option1/> + <option2/> + <option3/> + </options> + <field1/> + <field2/> + </fieldset2> +</xml> +EOF; + +$sxe = new SimpleXMLIterator($xml); +$rit = new RecursiveIteratorIterator($sxe, RecursiveIteratorIterator::LEAVES_ONLY); +foreach ($rit as $child) { + $path = ''; + $ancestry = $child->xpath('ancestor-or-self::*'); + foreach ($ancestry as $ancestor) { + $path .= $ancestor->getName() . '/'; + } + $path = substr($path, 0, strlen($path) - 1); + echo count($ancestry) . ' steps: ' . $path . PHP_EOL; +} +?> +===DONE=== +--EXPECT-- +3 steps: xml/fieldset1/field1 +3 steps: xml/fieldset1/field2 +4 steps: xml/fieldset2/options/option1 +4 steps: xml/fieldset2/options/option2 +4 steps: xml/fieldset2/options/option3 +3 steps: xml/fieldset2/field1 +3 steps: xml/fieldset2/field2 +===DONE=== diff --git a/ext/simplexml/tests/bug42369.phpt b/ext/simplexml/tests/bug42369.phpt new file mode 100644 index 0000000..e186770 --- /dev/null +++ b/ext/simplexml/tests/bug42369.phpt @@ -0,0 +1,25 @@ +--TEST-- +Bug #42369 (Implicit conversion to string leaks memory) +--SKIPIF-- +<?php if (!extension_loaded('simplexml')) echo 'skip simplexml extension is not loaded'; ?> +--FILE-- +<?php + $xml = '<?xml version="1.0" encoding="utf-8"?>'; + $x = simplexml_load_string($xml . "<q><x>foo</x></q>"); + + echo 'explicit conversion' . PHP_EOL; + for ($i = 0; $i < 100000; $i++) { + md5(strval($x->x)); + } + + echo 'no conversion' . PHP_EOL; + for ($i = 0; $i < 100000; $i++) { + md5($x->x); + } + +?> +===DONE=== +--EXPECT-- +explicit conversion +no conversion +===DONE===
\ No newline at end of file diff --git a/ext/simplexml/tests/bug43221.phpt b/ext/simplexml/tests/bug43221.phpt new file mode 100644 index 0000000..53b6efd --- /dev/null +++ b/ext/simplexml/tests/bug43221.phpt @@ -0,0 +1,20 @@ +--TEST-- +Bug #43221 (SimpleXML adding default namespace in addAttribute) +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php +$xml = simplexml_load_string('<?xml version="1.0" encoding="utf-8"?><root />'); +$n = $xml->addChild("node", "value"); +$n->addAttribute("a", "b"); +$n->addAttribute("c", "d", "http://bar.com"); +$n->addAttribute("foo:e", "f", "http://bar.com"); +print_r($xml->asXml()); +?> +===DONE=== +--EXPECTF-- +Warning: SimpleXMLElement::addAttribute(): Attribute requires prefix for namespace in %sbug43221.php on line %d +<?xml version="1.0" encoding="utf-8"?> +<root><node xmlns:foo="http://bar.com" a="b" foo:e="f">value</node></root> +===DONE=== +
\ No newline at end of file diff --git a/ext/simplexml/tests/bug44478.phpt b/ext/simplexml/tests/bug44478.phpt new file mode 100644 index 0000000..17a26f9 --- /dev/null +++ b/ext/simplexml/tests/bug44478.phpt @@ -0,0 +1,29 @@ +--TEST-- +Bug #44478 (Inconsistent behaviour when assigning new nodes) +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php +$xml_element = new simpleXMLElement('<root></root>'); +$xml_element->node1 = 'a & b'; +print $xml_element->node1."\n"; +$xml_element->node1 = 'a & b'; +print $xml_element->node1."\n"; +$xml_element->addChild('node2','a & b'); +print $xml_element->node2."\n"; +$xml_element->node2 = 'a & b'; +print $xml_element->node2."\n"; + +print $xml_element->asXML(); + +?> +===DONE=== +--EXPECTF-- +a & b +a & b +a & b +a & b +<?xml version="1.0"?> +<root><node1>a &#38; b</node1><node2>a & b</node2></root> +===DONE=== +
\ No newline at end of file diff --git a/ext/simplexml/tests/bug45553.phpt b/ext/simplexml/tests/bug45553.phpt new file mode 100644 index 0000000..b355c48 --- /dev/null +++ b/ext/simplexml/tests/bug45553.phpt @@ -0,0 +1,36 @@ +--TEST-- +Bug #45553 (Using XPath to return values for attributes with a namespace does not work) +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php +$xml =<<<XML +<xml xmlns:a="http://a"> + <data a:label="I am A" label="I am Nothing">test1</data> + <a:data a:label="I am a:A" label="I am a:Nothing">test2</a:data> +</xml> +XML; + +$x = simplexml_load_string($xml); +$x->registerXPathNamespace("a", "http://a"); + +$atts = $x->xpath("/xml/data/@a:label"); +echo $atts[0] . "\n"; +$atts = $x->xpath("/xml/a:data"); +echo $atts[0]->attributes() . "\n"; +$atts = $x->xpath("/xml/a:data/@a:label"); +echo $atts[0] . "\n"; +$atts = $x->xpath("/xml/a:data/@label"); +echo $atts[0] . "\n"; +$atts = $x->xpath("/xml/data/@label"); +echo $atts[0] . "\n"; +?> +===DONE=== +--EXPECTF-- +I am A +I am a:Nothing +I am a:A +I am a:Nothing +I am Nothing +===DONE=== +
\ No newline at end of file diff --git a/ext/simplexml/tests/bug46003.phpt b/ext/simplexml/tests/bug46003.phpt new file mode 100644 index 0000000..712675c --- /dev/null +++ b/ext/simplexml/tests/bug46003.phpt @@ -0,0 +1,35 @@ +--TEST-- +Bug #46003 (isset on nonexisting nodes return unexpected results) +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php +$xml =<<<XML +<r> + <p>Test</p> + <o d='h'> + <xx rr='info' /> + <yy rr='data' /> + </o> +</r> +XML; + +$x = simplexml_load_string($xml); + +var_dump(isset($x->p)); +var_dump(isset($x->p->o)); +var_dump(isset($x->o->yy)); +var_dump(isset($x->o->zz)); +var_dump(isset($x->o->text)); +var_dump(isset($x->o->xx)); +?> +===DONE=== +--EXPECTF-- +bool(true) +bool(false) +bool(true) +bool(false) +bool(false) +bool(true) +===DONE=== +
\ No newline at end of file diff --git a/ext/simplexml/tests/bug46047.phpt b/ext/simplexml/tests/bug46047.phpt new file mode 100644 index 0000000..0438154 --- /dev/null +++ b/ext/simplexml/tests/bug46047.phpt @@ -0,0 +1,53 @@ +--TEST-- +Bug #46047 (SimpleXML converts empty nodes into object with nested array) +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php +$xml = new SimpleXMLElement('<foo><bar><![CDATA[]]></bar><baz/></foo>', + LIBXML_NOCDATA); +print_r($xml); + +$xml = new SimpleXMLElement('<foo><bar></bar><baz/></foo>'); +print_r($xml); + +$xml = new SimpleXMLElement('<foo><bar/><baz/></foo>'); +print_r($xml); +?> +===DONE=== +--EXPECTF-- +SimpleXMLElement Object +( + [bar] => SimpleXMLElement Object + ( + ) + + [baz] => SimpleXMLElement Object + ( + ) + +) +SimpleXMLElement Object +( + [bar] => SimpleXMLElement Object + ( + ) + + [baz] => SimpleXMLElement Object + ( + ) + +) +SimpleXMLElement Object +( + [bar] => SimpleXMLElement Object + ( + ) + + [baz] => SimpleXMLElement Object + ( + ) + +) +===DONE=== +
\ No newline at end of file diff --git a/ext/simplexml/tests/bug46048.phpt b/ext/simplexml/tests/bug46048.phpt new file mode 100644 index 0000000..97fc9ed --- /dev/null +++ b/ext/simplexml/tests/bug46048.phpt @@ -0,0 +1,26 @@ +--TEST-- +Bug #46048 (SimpleXML top-level @attributes not part of iterator) +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php +$xml = ' +<data id="1"> + <key>value</key> +</data> +'; +$obj = simplexml_load_string($xml); +print_r(get_object_vars($obj)); +?> +===DONE=== +--EXPECT-- +Array +( + [@attributes] => Array + ( + [id] => 1 + ) + + [key] => value +) +===DONE=== diff --git a/ext/simplexml/tests/bug48601.phpt b/ext/simplexml/tests/bug48601.phpt new file mode 100644 index 0000000..0b81fac --- /dev/null +++ b/ext/simplexml/tests/bug48601.phpt @@ -0,0 +1,20 @@ +--TEST-- +Bug #48601 (xpath() returns FALSE for legitimate query) +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php + +$sxe = simplexml_load_string('<root><node1>1</node1></root>'); + +$nodes = $sxe->xpath("/root/node2/@test"); + +if (! is_array($nodes)) { + echo "An error occurred\n"; +} else { + echo "Result Count: " . count($nodes) . "\n"; +} + +?> +--EXPECTF-- +Result Count: 0 diff --git a/ext/simplexml/tests/bug51615.phpt b/ext/simplexml/tests/bug51615.phpt new file mode 100644 index 0000000..c96b3ae --- /dev/null +++ b/ext/simplexml/tests/bug51615.phpt @@ -0,0 +1,39 @@ +--TEST-- +Bug #51615 (PHP crash with wrong HTML in SimpleXML) +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; + if (!extension_loaded("dom")) print "skip"; +?> +--FILE-- +<?php + +$dom = new DOMDocument; +$dom->loadHTML('<span title=""y">x</span><span title=""z">x</span>'); +$html = simplexml_import_dom($dom); + +var_dump($html->body->span); + +foreach ($html->body->span as $obj) { + var_dump((string)$obj->title); +} + +?> +--EXPECTF-- +Warning: DOMDocument::loadHTML(): error parsing attribute name in Entity, line: 1 in %s on line %d + +Warning: DOMDocument::loadHTML(): error parsing attribute name in Entity, line: 1 in %s on line %d +object(SimpleXMLElement)#%d (3) { + ["@attributes"]=> + array(2) { + ["title"]=> + string(0) "" + ["y"]=> + string(0) "" + } + [0]=> + string(1) "x" + [1]=> + string(1) "x" +} +string(0) "" +string(0) "" diff --git a/ext/simplexml/tests/feature55218.phpt b/ext/simplexml/tests/feature55218.phpt new file mode 100644 index 0000000..25ea534 --- /dev/null +++ b/ext/simplexml/tests/feature55218.phpt @@ -0,0 +1,117 @@ +--TEST-- +Bug #55218 getDocNamespaces from current element and not root +--SKIPIF-- +<?php +if (!extension_loaded("simplexml")) print "skip SimpleXML not present"; +if (!extension_loaded("libxml")) print "skip LibXML not present"; +?> +--FILE-- +<?php + +$x = new SimpleXMLElement( +'<?xml version="1.0" standalone="yes"?> +<people xmlns:p="http://example.org/p" > + <person id="1" xmlns:t="http://example.org/t" > + <t:name>John Doe</t:name> + </person> + <person id="2">Susie Q. Public</person> + <o> + <p:div>jdslkfjsldk jskdfjsmlkjfkldjkjflskj kljfslkjf sldk</p:div> + </o> +</people>'); + +echo "getDocNamespaces\n"; +echo "\nBackwards Compatibility:\n"; +echo "recursion:\n"; + +var_dump ( $x->getDocNamespaces(true) ) ; +var_dump( $x->person[0]->getDocNamespaces(true) ); +var_dump( $x->person[1]->getDocNamespaces(true) ); + +echo "\nnon recursive:\n"; + +var_dump( $x->getDocNamespaces(false) ); +var_dump( $x->person[0]->getDocNamespaces(false) ); +var_dump( $x->person[1]->getDocNamespaces(false) ); + +echo "\n\nUsing new 'from_root' bool set to false:\n"; +echo "recursion:\n"; + +var_dump ( $x->getDocNamespaces(true, false) ) ; +var_dump( $x->person[0]->getDocNamespaces(true, false) ); +var_dump( $x->person[1]->getDocNamespaces(true, false) ); + +echo "\nnon recursive:\n"; + +var_dump( $x->getDocNamespaces(false, false) ); +var_dump( $x->person[0]->getDocNamespaces(false, false) ); +var_dump( $x->person[1]->getDocNamespaces(false, false) ); + +?> +===DONE=== +--EXPECTF-- +getDocNamespaces + +Backwards Compatibility: +recursion: +array(2) { + ["p"]=> + string(20) "http://example.org/p" + ["t"]=> + string(20) "http://example.org/t" +} +array(2) { + ["p"]=> + string(20) "http://example.org/p" + ["t"]=> + string(20) "http://example.org/t" +} +array(2) { + ["p"]=> + string(20) "http://example.org/p" + ["t"]=> + string(20) "http://example.org/t" +} + +non recursive: +array(1) { + ["p"]=> + string(20) "http://example.org/p" +} +array(1) { + ["p"]=> + string(20) "http://example.org/p" +} +array(1) { + ["p"]=> + string(20) "http://example.org/p" +} + + +Using new 'from_root' bool set to false: +recursion: +array(2) { + ["p"]=> + string(20) "http://example.org/p" + ["t"]=> + string(20) "http://example.org/t" +} +array(1) { + ["t"]=> + string(20) "http://example.org/t" +} +array(0) { +} + +non recursive: +array(1) { + ["p"]=> + string(20) "http://example.org/p" +} +array(1) { + ["t"]=> + string(20) "http://example.org/t" +} +array(0) { +} +===DONE===
\ No newline at end of file diff --git a/ext/simplexml/tests/profile01.phpt b/ext/simplexml/tests/profile01.phpt new file mode 100644 index 0000000..91b9544 --- /dev/null +++ b/ext/simplexml/tests/profile01.phpt @@ -0,0 +1,18 @@ +--TEST-- +SimpleXML [profile]: Accessing a simple node +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php +$root = simplexml_load_string('<?xml version="1.0"?> +<root> + <child>Hello</child> +</root> +'); + +echo $root->child; +echo "\n---Done---\n"; +?> +--EXPECT-- +Hello +---Done--- diff --git a/ext/simplexml/tests/profile02.phpt b/ext/simplexml/tests/profile02.phpt new file mode 100644 index 0000000..14b5bb8 --- /dev/null +++ b/ext/simplexml/tests/profile02.phpt @@ -0,0 +1,21 @@ +--TEST-- +SimpleXML [profile]: Accessing an array of subnodes +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php +$root = simplexml_load_string('<?xml version="1.0"?> +<root> + <child>Hello</child> + <child>World</child> +</root> +'); + +foreach ($root->child as $child) { + echo "$child "; +} +echo "\n---Done---\n"; +?> +--EXPECT-- +Hello World +---Done--- diff --git a/ext/simplexml/tests/profile03.phpt b/ext/simplexml/tests/profile03.phpt new file mode 100644 index 0000000..14f1c5f --- /dev/null +++ b/ext/simplexml/tests/profile03.phpt @@ -0,0 +1,18 @@ +--TEST-- +SimpleXML [profile]: Accessing an attribute +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php +$root = simplexml_load_string('<?xml version="1.0"?> +<root> + <child attribute="Sample" /> +</root> +'); + +echo $root->child['attribute']; +echo "\n---Done---\n"; +?> +--EXPECT-- +Sample +---Done--- diff --git a/ext/simplexml/tests/profile04.phpt b/ext/simplexml/tests/profile04.phpt new file mode 100644 index 0000000..27714e9 --- /dev/null +++ b/ext/simplexml/tests/profile04.phpt @@ -0,0 +1,18 @@ +--TEST-- +SimpleXML [profile]: Accessing a namespaced element +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php +$root = simplexml_load_string('<?xml version="1.0"?> +<root xmlns:reserved="reserved-ns"> + <reserved:child>Hello</reserved:child> +</root> +'); + +echo $root->children('reserved-ns')->child; +echo "\n---Done---\n"; +?> +--EXPECT-- +Hello +---Done--- diff --git a/ext/simplexml/tests/profile05.phpt b/ext/simplexml/tests/profile05.phpt new file mode 100644 index 0000000..f696221 --- /dev/null +++ b/ext/simplexml/tests/profile05.phpt @@ -0,0 +1,18 @@ +--TEST-- +SimpleXML [profile]: Accessing an aliased namespaced element +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php +error_reporting(E_ALL & ~E_NOTICE); +$root = simplexml_load_string('<?xml version="1.0"?> +<root xmlns:reserved="reserved-ns"> + <reserved:child>Hello</reserved:child> +</root> +'); + +echo $root->children('reserved')->child; +echo "\n---Done---\n"; +?> +--EXPECT-- +---Done--- diff --git a/ext/simplexml/tests/profile06.phpt b/ext/simplexml/tests/profile06.phpt new file mode 100644 index 0000000..e519fa9 --- /dev/null +++ b/ext/simplexml/tests/profile06.phpt @@ -0,0 +1,20 @@ +--TEST-- +SimpleXML [profile]: Accessing a namespaced attribute +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php +error_reporting(E_ALL & ~E_NOTICE); +$root = simplexml_load_string('<?xml version="1.0"?> +<root xmlns:reserved="reserved-ns"> + <child reserved:attribute="Sample" /> +</root> +'); + +$attr = $root->child->attributes('reserved-ns'); +echo $attr['attribute']; +echo "\n---Done---\n"; +?> +--EXPECT-- +Sample +---Done--- diff --git a/ext/simplexml/tests/profile07.phpt b/ext/simplexml/tests/profile07.phpt new file mode 100644 index 0000000..c8a4269 --- /dev/null +++ b/ext/simplexml/tests/profile07.phpt @@ -0,0 +1,23 @@ +--TEST-- +SimpleXML [profile]: Accessing an aliased namespaced attribute +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php +error_reporting(E_ALL & ~E_NOTICE); +$root = simplexml_load_string('<?xml version="1.0"?> +<root xmlns:reserved="reserved-ns"> + <child reserved:attribute="Sample" /> +</root> +'); + +$rsattr = $root->child->attributes('reserved'); +$myattr = $root->child->attributes('reserved-ns'); + +echo $rsattr['attribute']; +echo $myattr['attribute']; +echo "\n---Done---\n"; +?> +--EXPECT-- +Sample +---Done--- diff --git a/ext/simplexml/tests/profile08.phpt b/ext/simplexml/tests/profile08.phpt new file mode 100644 index 0000000..bbb69b7 --- /dev/null +++ b/ext/simplexml/tests/profile08.phpt @@ -0,0 +1,18 @@ +--TEST-- +SimpleXML [profile]: Accessing a namespaced attribute without a namespace +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php +error_reporting(E_ALL & ~E_NOTICE); +$root = simplexml_load_string('<?xml version="1.0"?> +<root xmlns:reserved="reserved-ns"> + <child reserved:attribute="Sample" /> +</root> +'); + +echo $root->child['attribute']; +echo "\n---Done---\n"; +?> +--EXPECT-- +---Done--- diff --git a/ext/simplexml/tests/profile09.phpt b/ext/simplexml/tests/profile09.phpt new file mode 100644 index 0000000..714572d --- /dev/null +++ b/ext/simplexml/tests/profile09.phpt @@ -0,0 +1,19 @@ +--TEST-- +SimpleXML [profile]: Accessing a namespaced element without a namespace +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php +error_reporting(E_ALL & ~E_NOTICE); +$root = simplexml_load_string('<?xml version="1.0"?> +<root xmlns:reserved="reserved-ns"> + <reserved:child>Hello</reserved:child> +</root> +'); + +echo $root->child; +echo "\n---Done---\n"; +?> +--EXPECT-- + +---Done--- diff --git a/ext/simplexml/tests/profile10.phpt b/ext/simplexml/tests/profile10.phpt new file mode 100644 index 0000000..6ef7456 --- /dev/null +++ b/ext/simplexml/tests/profile10.phpt @@ -0,0 +1,25 @@ +--TEST-- +SimpleXML [profile]: Accessing two attributes with the same name, but different namespaces +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php +error_reporting(E_ALL & ~E_NOTICE); +$root = simplexml_load_string('<?xml version="1.0"?> +<root xmlns:reserved="reserved-ns" xmlns:special="special-ns"> + <child reserved:attribute="Sample" special:attribute="Test" /> +</root> +'); + +$rsattr = $root->child->attributes('reserved-ns'); +$spattr = $root->child->attributes('special-ns'); + +echo $rsattr['attribute']; +echo "\n"; +echo $spattr['attribute']; +echo "\n---Done---\n"; +?> +--EXPECT-- +Sample +Test +---Done--- diff --git a/ext/simplexml/tests/profile11.phpt b/ext/simplexml/tests/profile11.phpt new file mode 100644 index 0000000..54c31bf --- /dev/null +++ b/ext/simplexml/tests/profile11.phpt @@ -0,0 +1,35 @@ +--TEST-- +SimpleXML [profile]: Accessing two elements with the same name, but different namespaces +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php +error_reporting(E_ALL & ~E_NOTICE); +$root = simplexml_load_string('<?xml version="1.0"?> +<root xmlns:reserved="reserved-ns" xmlns:special="special-ns"> + <reserved:child>Hello</reserved:child> + <special:child>World</special:child> +</root> +'); + +var_dump($root->children('reserved-ns')->child); +var_dump($root->children('special-ns')->child); +var_dump((string)$root->children('reserved-ns')->child); +var_dump((string)$root->children('special-ns')->child); +var_dump($root->child); +?> +===DONE=== +--EXPECTF-- +object(SimpleXMLElement)#%d (1) { + [0]=> + string(5) "Hello" +} +object(SimpleXMLElement)#%d (1) { + [0]=> + string(5) "World" +} +string(5) "Hello" +string(5) "World" +object(SimpleXMLElement)#%d (0) { +} +===DONE=== diff --git a/ext/simplexml/tests/profile12.phpt b/ext/simplexml/tests/profile12.phpt new file mode 100644 index 0000000..51a0d35 --- /dev/null +++ b/ext/simplexml/tests/profile12.phpt @@ -0,0 +1,74 @@ +--TEST-- +SimpleXML [profile]: Accessing namespaced root and non namespaced children +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php + +$xml =<<<EOF +<?xml version="1.0" encoding="utf-8"?> +<soap:Envelope +xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" +xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +xmlns:xsd="http://www.w3.org/2001/XMLSchema" +> +<soap:Body> +<businessList foo="bar"> +<businessInfo businessKey="bla"/> +</businessList> +</soap:Body> +</soap:Envelope> +EOF; + +$sxe = simplexml_load_string($xml); +$nsl = $sxe->getNamespaces(); +var_dump($nsl); + +$sxe = simplexml_load_string($xml, NULL, 0, $nsl['soap']); +var_dump($sxe->Body); +var_dump($sxe->Body->children('')); +var_dump($sxe->Body->children('')->businessList); + +?> +===DONE=== +--EXPECTF-- +array(1) { + ["soap"]=> + string(41) "http://schemas.xmlsoap.org/soap/envelope/" +} +object(SimpleXMLElement)#%s (0) { +} +object(SimpleXMLElement)#%s (1) { + ["businessList"]=> + object(SimpleXMLElement)#%s (2) { + ["@attributes"]=> + array(1) { + ["foo"]=> + string(3) "bar" + } + ["businessInfo"]=> + object(SimpleXMLElement)#%s (1) { + ["@attributes"]=> + array(1) { + ["businessKey"]=> + string(3) "bla" + } + } + } +} +object(SimpleXMLElement)#%s (2) { + ["@attributes"]=> + array(1) { + ["foo"]=> + string(3) "bar" + } + ["businessInfo"]=> + object(SimpleXMLElement)#%s (1) { + ["@attributes"]=> + array(1) { + ["businessKey"]=> + string(3) "bla" + } + } +} +===DONE=== diff --git a/ext/simplexml/tests/profile13.phpt b/ext/simplexml/tests/profile13.phpt new file mode 100644 index 0000000..2ae89e7 --- /dev/null +++ b/ext/simplexml/tests/profile13.phpt @@ -0,0 +1,75 @@ +--TEST-- +SimpleXML [profile]: Accessing by namespace prefix +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php + +$xml =<<<EOF +<?xml version="1.0" encoding="utf-8"?> +<soap:Envelope +xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" +xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +xmlns:xsd="http://www.w3.org/2001/XMLSchema" +> +<soap:Body> +<businessList foo="bar"> +<businessInfo businessKey="bla"/> +</businessList> +</soap:Body> +</soap:Envelope> +EOF; + +$sxe = simplexml_load_string($xml); +var_dump($sxe->children('soap', 1)); + +$sxe = simplexml_load_string($xml, NULL, 0, 'soap', 1); +var_dump($sxe->Body); +var_dump($sxe->Body->children('')); +var_dump($sxe->Body->children('')->businessList); + +?> +===DONE=== +<?php exit(0); ?> +--EXPECTF-- +object(SimpleXMLElement)#%d (1) { + ["Body"]=> + object(SimpleXMLElement)#%d (0) { + } +} +object(SimpleXMLElement)#%d (0) { +} +object(SimpleXMLElement)#%d (1) { + ["businessList"]=> + object(SimpleXMLElement)#%d (2) { + ["@attributes"]=> + array(1) { + ["foo"]=> + string(3) "bar" + } + ["businessInfo"]=> + object(SimpleXMLElement)#%d (1) { + ["@attributes"]=> + array(1) { + ["businessKey"]=> + string(3) "bla" + } + } + } +} +object(SimpleXMLElement)#%d (2) { + ["@attributes"]=> + array(1) { + ["foo"]=> + string(3) "bar" + } + ["businessInfo"]=> + object(SimpleXMLElement)#%d (1) { + ["@attributes"]=> + array(1) { + ["businessKey"]=> + string(3) "bla" + } + } +} +===DONE=== diff --git a/ext/simplexml/tests/simplexml_import_dom.phpt b/ext/simplexml/tests/simplexml_import_dom.phpt new file mode 100644 index 0000000..e108e05 --- /dev/null +++ b/ext/simplexml/tests/simplexml_import_dom.phpt @@ -0,0 +1,22 @@ +--TEST-- +SimpleXML [interop]: simplexml_import_dom +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) die("skip"); ?> +<?php if (!extension_loaded("dom")) die("skip dom extension not loaded"); ?> +--FILE-- +<?php +$dom = new domDocument; +$dom->load(dirname(__FILE__)."/book.xml"); +if(!$dom) { + echo "Error while parsing the document\n"; + exit; +} +$s = simplexml_import_dom($dom); +$books = $s->book; +foreach ($books as $book) { + echo "{$book->title} was written by {$book->author}\n"; +} +?> +--EXPECT-- +The Grapes of Wrath was written by John Steinbeck +The Pearl was written by John Steinbeck diff --git a/ext/simplexml/tests/simplexml_load_file.phpt b/ext/simplexml/tests/simplexml_load_file.phpt new file mode 100644 index 0000000..8dc6481 --- /dev/null +++ b/ext/simplexml/tests/simplexml_load_file.phpt @@ -0,0 +1,32 @@ +--TEST-- +simplexml_load_file() +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) die("skip"); ?> +--FILE-- +<?php + $simple = simplexml_load_file(dirname(__FILE__)."/book.xml"); + + var_dump($simple); + echo "Done"; +?> +--EXPECTF-- +object(SimpleXMLElement)#1 (1) { + ["book"]=> + array(2) { + [0]=> + object(SimpleXMLElement)#2 (2) { + ["title"]=> + string(19) "The Grapes of Wrath" + ["author"]=> + string(14) "John Steinbeck" + } + [1]=> + object(SimpleXMLElement)#3 (2) { + ["title"]=> + string(9) "The Pearl" + ["author"]=> + string(14) "John Steinbeck" + } + } +} +Done
\ No newline at end of file diff --git a/ext/simplexml/tests/sxe.dtd b/ext/simplexml/tests/sxe.dtd new file mode 100755 index 0000000..b75a792 --- /dev/null +++ b/ext/simplexml/tests/sxe.dtd @@ -0,0 +1,34 @@ +<?xml encoding='US-ASCII'?>
+
+<!ELEMENT sxe (elem1+, elem11, elem22*)>
+<!ATTLIST sxe id CDATA #implied>
+
+<!ELEMENT elem1 elem2*>
+<!ATTLIST elem1 attr1 CDATA #required
+ attr2 CDATA "default>
+
+<!ELEMENT elem2 elem3*>
+<!ATTLIST elem2 att25 CDATA #implied
+ att42 CDATA #implied>
+
+<!ELEMENT elem3 elem4*>
+<!ATTLIST elem3>
+
+<!ELEMENT elem4 EMPTY>
+<!ATTLIST elem4>
+
+<!ELEMENT elem11 elem111*>
+<!ATTLIST elem11>
+
+<!ELEMNET elem111 elem1111*>
+<!ATTLIST elem111>
+
+<!ELEMENT elem1111 EMPTY>
+<!ATTLIST elem1111>
+
+<!ELEMENT elem22 elem222*>
+<!ATTLIST elem22 attr22 CDATA #implied>
+
+<!ELEMENT elem222 EMPTY>
+<!ATTLIST elem222>
+
diff --git a/ext/simplexml/tests/sxe.ent b/ext/simplexml/tests/sxe.ent new file mode 100755 index 0000000..8f86465 --- /dev/null +++ b/ext/simplexml/tests/sxe.ent @@ -0,0 +1 @@ +<!ENTITY included-entity "This is text included from an entity"> diff --git a/ext/simplexml/tests/sxe.xml b/ext/simplexml/tests/sxe.xml new file mode 100755 index 0000000..909b4e6 --- /dev/null +++ b/ext/simplexml/tests/sxe.xml @@ -0,0 +1,17 @@ +<?xml version='1.0'?> +<!DOCTYPE sxe SYSTEM "notfound.dtd" [ +<!ENTITY % incent SYSTEM "sxe.ent"> +%incent; +]> +<sxe id="elem1"> + <elem1 attr1='first'> + <!-- comment --> + <elem2> + <elem3> + <elem4> + <?test processing instruction ?> + </elem4> + </elem3> + </elem2> + </elem1> +</sxe>
\ No newline at end of file diff --git a/ext/simplexml/tests/sxe_001.phpt b/ext/simplexml/tests/sxe_001.phpt new file mode 100644 index 0000000..bb93eea --- /dev/null +++ b/ext/simplexml/tests/sxe_001.phpt @@ -0,0 +1,63 @@ +--TEST-- +SPL: SimpleXMLIterator +--SKIPIF-- +<?php +if (!extension_loaded("simplexml")) print "skip SimpleXML not present"; +if (!extension_loaded("libxml")) print "skip LibXML not present"; +?> +--FILE-- +<?php + +$xml =<<<EOF +<?xml version='1.0'?> +<!DOCTYPE sxe SYSTEM "notfound.dtd"> +<sxe id="elem1"> + <elem1 attr1='first'> + <!-- comment --> + <elem2> + <elem3> + <elem4> + <?test processing instruction ?> + </elem4> + </elem3> + </elem2> + </elem1> +</sxe> +EOF; + +var_dump(simplexml_load_string((binary)$xml, 'SimpleXMLIterator')); + +?> +===DONE=== +--EXPECTF-- +object(SimpleXMLIterator)#%d (2) { + ["@attributes"]=> + array(1) { + ["id"]=> + string(5) "elem1" + } + ["elem1"]=> + object(SimpleXMLIterator)#%d (3) { + ["@attributes"]=> + array(1) { + ["attr1"]=> + string(5) "first" + } + ["comment"]=> + object(SimpleXMLIterator)#%d (0) { + } + ["elem2"]=> + object(SimpleXMLIterator)#%d (1) { + ["elem3"]=> + object(SimpleXMLIterator)#%d (1) { + ["elem4"]=> + object(SimpleXMLIterator)#%d (1) { + ["test"]=> + object(SimpleXMLIterator)#%d (0) { + } + } + } + } + } +} +===DONE=== diff --git a/ext/simplexml/tests/sxe_002.phpt b/ext/simplexml/tests/sxe_002.phpt new file mode 100644 index 0000000..b937b01 --- /dev/null +++ b/ext/simplexml/tests/sxe_002.phpt @@ -0,0 +1,75 @@ +--TEST-- +SPL: SimpleXMLIterator and recursion +--SKIPIF-- +<?php +if (!extension_loaded('simplexml')) print 'skip'; +if (!extension_loaded("libxml")) print "skip LibXML not present"; +?> +--FILE-- +<?php + +$xml =<<<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; + +$sxe = simplexml_load_string((binary)$xml, 'SimpleXMLIterator'); + +foreach(new RecursiveIteratorIterator($sxe, 1) as $name => $data) { + var_dump($name); + var_dump(get_class($data)); + var_dump(trim($data)); +} + +echo "===DUMP===\n"; + +var_dump(get_class($sxe)); +var_dump(trim($sxe->elem1)); + +?> +===DONE=== +--EXPECT-- +string(5) "elem1" +string(17) "SimpleXMLIterator" +string(10) "Bla bla 1." +string(5) "elem2" +string(17) "SimpleXMLIterator" +string(28) "Here we have some text data." +string(5) "elem3" +string(17) "SimpleXMLIterator" +string(19) "And here some more." +string(5) "elem4" +string(17) "SimpleXMLIterator" +string(15) "Wow once again." +string(6) "elem11" +string(17) "SimpleXMLIterator" +string(10) "Bla bla 2." +string(7) "elem111" +string(17) "SimpleXMLIterator" +string(7) "Foo Bar" +===DUMP=== +string(17) "SimpleXMLIterator" +string(10) "Bla bla 1." +===DONE=== diff --git a/ext/simplexml/tests/sxe_003.phpt b/ext/simplexml/tests/sxe_003.phpt new file mode 100644 index 0000000..58c7523 --- /dev/null +++ b/ext/simplexml/tests/sxe_003.phpt @@ -0,0 +1,77 @@ +--TEST-- +SPL: SimpleXMLIterator and getChildren() +--SKIPIF-- +<?php +if (!extension_loaded('simplexml')) print 'skip'; +if (!extension_loaded("libxml")) print "skip LibXML not present"; +?> +--FILE-- +<?php + +$xml =<<<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; + +$sxe = simplexml_load_string((binary)$xml, 'SimpleXMLIterator'); + +foreach($sxe->getChildren() as $name => $data) { + var_dump($name); + var_dump(get_class($data)); + var_dump(trim($data)); +} + +echo "===RESET===\n"; + +for ($sxe->rewind(); $sxe->valid(); $sxe->next()) { + var_dump($sxe->hasChildren()); + var_dump(trim($sxe->key())); + var_dump(trim($sxe->current())); + foreach($sxe->getChildren() as $name => $data) { + var_dump($name); + var_dump(get_class($data)); + var_dump(trim($data)); + } +} + +?> +===DONE=== +--EXPECTF-- + +Warning: Invalid argument supplied for foreach() in %ssxe_003.php on line %d +===RESET=== +bool(true) +string(5) "elem1" +string(10) "Bla bla 1." +string(5) "elem2" +string(17) "SimpleXMLIterator" +string(28) "Here we have some text data." +bool(true) +string(6) "elem11" +string(10) "Bla bla 2." +string(7) "elem111" +string(17) "SimpleXMLIterator" +string(7) "Foo Bar" +===DONE=== diff --git a/ext/simplexml/tests/sxe_004.phpt b/ext/simplexml/tests/sxe_004.phpt new file mode 100644 index 0000000..20431de --- /dev/null +++ b/ext/simplexml/tests/sxe_004.phpt @@ -0,0 +1,145 @@ +--TEST-- +SPL: SimpleXMLIterator and overridden iterator methods() +--SKIPIF-- +<?php +if (!extension_loaded('simplexml')) print 'skip'; +if (!extension_loaded("libxml")) print "skip LibXML not present"; +?> +--FILE-- +<?php + +$xml =<<<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; + +class SXETest extends SimpleXMLIterator +{ + function rewind() + { + echo __METHOD__ . "\n"; + return parent::rewind(); + } + function valid() + { + echo __METHOD__ . "\n"; + return parent::valid(); + } + function current() + { + echo __METHOD__ . "\n"; + return parent::current(); + } + function key() + { + echo __METHOD__ . "\n"; + return parent::key(); + } + function next() + { + echo __METHOD__ . "\n"; + return parent::next(); + } + function hasChildren() + { + echo __METHOD__ . "\n"; + return parent::hasChildren(); + } + function getChildren() + { + echo __METHOD__ . "\n"; + return parent::getChildren(); + } +} + +$sxe = new SXETest((binary)$xml); +$rit = new RecursiveIteratorIterator($sxe, RecursiveIteratorIterator::SELF_FIRST); + +foreach($rit as $data) { + var_dump(get_class($data)); + var_dump(trim($data)); +} + +?> +===DONE=== +--EXPECTF-- +SXETest::rewind +SXETest::valid +SXETest::hasChildren +SXETest::valid +SXETest::current +string(7) "SXETest" +string(10) "Bla bla 1." +SXETest::getChildren +SXETest::rewind +SXETest::valid +SXETest::hasChildren +SXETest::valid +SXETest::current +string(7) "SXETest" +string(28) "Here we have some text data." +SXETest::getChildren +SXETest::rewind +SXETest::valid +SXETest::hasChildren +SXETest::valid +SXETest::current +string(7) "SXETest" +string(19) "And here some more." +SXETest::getChildren +SXETest::rewind +SXETest::valid +SXETest::hasChildren +SXETest::valid +SXETest::current +string(7) "SXETest" +string(15) "Wow once again." +SXETest::next +SXETest::valid +SXETest::next +SXETest::valid +SXETest::next +SXETest::valid +SXETest::next +SXETest::valid +SXETest::hasChildren +SXETest::valid +SXETest::current +string(7) "SXETest" +string(10) "Bla bla 2." +SXETest::getChildren +SXETest::rewind +SXETest::valid +SXETest::hasChildren +SXETest::valid +SXETest::current +string(7) "SXETest" +string(7) "Foo Bar" +SXETest::next +SXETest::valid +SXETest::next +SXETest::valid +SXETest::valid +===DONE=== diff --git a/ext/simplexml/tests/sxe_005.phpt b/ext/simplexml/tests/sxe_005.phpt new file mode 100644 index 0000000..183d351 --- /dev/null +++ b/ext/simplexml/tests/sxe_005.phpt @@ -0,0 +1,44 @@ +--TEST-- +SPL: SimpleXMLIterator and overriden count() +--SKIPIF-- +<?php +if (!extension_loaded('simplexml')) print 'skip'; +if (!extension_loaded("libxml")) print "skip LibXML not present"; +?> +--FILE-- +<?php + +$xml =<<<EOF +<?xml version='1.0'?> +<sxe> + <elem1/> + <elem2/> + <elem2/> +</sxe> +EOF; + +class SXETest extends SimpleXMLIterator +{ + function count() + { + echo __METHOD__ . "\n"; + return parent::count(); + } +} + +$sxe = new SXETest((binary)$xml); + +var_dump(count($sxe)); +var_dump(count($sxe->elem1)); +var_dump(count($sxe->elem2)); + +?> +===DONE=== +--EXPECT-- +SXETest::count +int(3) +SXETest::count +int(1) +SXETest::count +int(2) +===DONE=== |