summaryrefslogtreecommitdiff
path: root/ext/simplexml
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2013-03-14 05:42:27 +0000
committer <>2013-04-03 16:25:08 +0000
commitc4dd7a1a684490673e25aaf4fabec5df138854c4 (patch)
tree4d57c44caae4480efff02b90b9be86f44bf25409 /ext/simplexml
downloadphp2-master.tar.gz
Imported from /home/lorry/working-area/delta_php2/php-5.4.13.tar.bz2.HEADphp-5.4.13master
Diffstat (limited to 'ext/simplexml')
-rw-r--r--ext/simplexml/CREDITS2
-rwxr-xr-xext/simplexml/README34
-rw-r--r--ext/simplexml/config.m427
-rw-r--r--ext/simplexml/config.w3223
-rw-r--r--ext/simplexml/examples/book.php8
-rw-r--r--ext/simplexml/examples/book.xml10
-rw-r--r--ext/simplexml/examples/interop.php27
-rw-r--r--ext/simplexml/examples/security.php6
-rw-r--r--ext/simplexml/examples/security.xml4
-rw-r--r--ext/simplexml/examples/xpath.php9
-rw-r--r--ext/simplexml/php_simplexml.h102
-rw-r--r--ext/simplexml/php_simplexml_exports.h67
-rw-r--r--ext/simplexml/simplexml.c2683
-rw-r--r--ext/simplexml/simplexml.dsp111
-rw-r--r--ext/simplexml/sxe.c219
-rw-r--r--ext/simplexml/sxe.h39
-rw-r--r--ext/simplexml/tests/000.phpt254
-rwxr-xr-xext/simplexml/tests/000.xml16
-rw-r--r--ext/simplexml/tests/001.phpt43
-rw-r--r--ext/simplexml/tests/002.phpt64
-rw-r--r--ext/simplexml/tests/003.phpt69
-rw-r--r--ext/simplexml/tests/004.phpt68
-rw-r--r--ext/simplexml/tests/005.phpt40
-rw-r--r--ext/simplexml/tests/006.phpt80
-rw-r--r--ext/simplexml/tests/007.phpt97
-rw-r--r--ext/simplexml/tests/008.phpt48
-rw-r--r--ext/simplexml/tests/009.phpt45
-rw-r--r--ext/simplexml/tests/009b.phpt35
-rw-r--r--ext/simplexml/tests/010.phpt64
-rw-r--r--ext/simplexml/tests/011.phpt47
-rw-r--r--ext/simplexml/tests/012.phpt40
-rw-r--r--ext/simplexml/tests/013.phpt23
-rw-r--r--ext/simplexml/tests/014.phpt60
-rw-r--r--ext/simplexml/tests/014a.phpt56
-rw-r--r--ext/simplexml/tests/014b.phpt55
-rw-r--r--ext/simplexml/tests/015.phpt56
-rw-r--r--ext/simplexml/tests/016.phpt57
-rw-r--r--ext/simplexml/tests/016a.phpt29
-rw-r--r--ext/simplexml/tests/017.phpt86
-rw-r--r--ext/simplexml/tests/018.phpt65
-rw-r--r--ext/simplexml/tests/019.phpt80
-rw-r--r--ext/simplexml/tests/020.phpt21
-rw-r--r--ext/simplexml/tests/021.phpt25
-rw-r--r--ext/simplexml/tests/022.phpt62
-rw-r--r--ext/simplexml/tests/023.phpt36
-rw-r--r--ext/simplexml/tests/024.phpt175
-rw-r--r--ext/simplexml/tests/025.phpt92
-rw-r--r--ext/simplexml/tests/026.phpt40
-rw-r--r--ext/simplexml/tests/027.phpt83
-rw-r--r--ext/simplexml/tests/028.phpt42
-rw-r--r--ext/simplexml/tests/029.phpt40
-rw-r--r--ext/simplexml/tests/030.phpt44
-rw-r--r--ext/simplexml/tests/031.phpt57
-rw-r--r--ext/simplexml/tests/032.phpt45
-rw-r--r--ext/simplexml/tests/033.phpt137
-rw-r--r--ext/simplexml/tests/034.phpt24
-rw-r--r--ext/simplexml/tests/035.phpt26
-rw-r--r--ext/simplexml/tests/036.phpt22
-rw-r--r--ext/simplexml/tests/SimpleXMLElement_addAttribute_basic.phpt21
-rw-r--r--ext/simplexml/tests/SimpleXMLElement_addAttribute_required_attribute_name.phpt18
-rw-r--r--ext/simplexml/tests/book.xml10
-rw-r--r--ext/simplexml/tests/bug24392.phpt22
-rw-r--r--ext/simplexml/tests/bug24392.xml76
-rw-r--r--ext/simplexml/tests/bug25756.xsd24
-rw-r--r--ext/simplexml/tests/bug25756_1.xml13
-rw-r--r--ext/simplexml/tests/bug25756_2.xml13
-rw-r--r--ext/simplexml/tests/bug26976.phpt28
-rw-r--r--ext/simplexml/tests/bug27010.phpt34
-rw-r--r--ext/simplexml/tests/bug35785.phpt30
-rw-r--r--ext/simplexml/tests/bug36611.phpt30
-rw-r--r--ext/simplexml/tests/bug37076.phpt16
-rw-r--r--ext/simplexml/tests/bug37076_1.phpt18
-rw-r--r--ext/simplexml/tests/bug37386.phpt25
-rw-r--r--ext/simplexml/tests/bug37565.phpt31
-rw-r--r--ext/simplexml/tests/bug38347.phpt28
-rw-r--r--ext/simplexml/tests/bug38354.phpt28
-rw-r--r--ext/simplexml/tests/bug38406.phpt33
-rw-r--r--ext/simplexml/tests/bug38424.phpt26
-rw-r--r--ext/simplexml/tests/bug39662.phpt37
-rw-r--r--ext/simplexml/tests/bug39760.phpt40
-rw-r--r--ext/simplexml/tests/bug40451.phpt24
-rw-r--r--ext/simplexml/tests/bug41175.phpt18
-rw-r--r--ext/simplexml/tests/bug41582.phpt20
-rw-r--r--ext/simplexml/tests/bug41861.phpt42
-rw-r--r--ext/simplexml/tests/bug41867.phpt18
-rw-r--r--ext/simplexml/tests/bug41947.phpt18
-rw-r--r--ext/simplexml/tests/bug42259.phpt49
-rw-r--r--ext/simplexml/tests/bug42369.phpt25
-rw-r--r--ext/simplexml/tests/bug43221.phpt20
-rw-r--r--ext/simplexml/tests/bug44478.phpt29
-rw-r--r--ext/simplexml/tests/bug45553.phpt36
-rw-r--r--ext/simplexml/tests/bug46003.phpt35
-rw-r--r--ext/simplexml/tests/bug46047.phpt53
-rw-r--r--ext/simplexml/tests/bug46048.phpt26
-rw-r--r--ext/simplexml/tests/bug48601.phpt20
-rw-r--r--ext/simplexml/tests/bug51615.phpt39
-rw-r--r--ext/simplexml/tests/feature55218.phpt117
-rw-r--r--ext/simplexml/tests/profile01.phpt18
-rw-r--r--ext/simplexml/tests/profile02.phpt21
-rw-r--r--ext/simplexml/tests/profile03.phpt18
-rw-r--r--ext/simplexml/tests/profile04.phpt18
-rw-r--r--ext/simplexml/tests/profile05.phpt18
-rw-r--r--ext/simplexml/tests/profile06.phpt20
-rw-r--r--ext/simplexml/tests/profile07.phpt23
-rw-r--r--ext/simplexml/tests/profile08.phpt18
-rw-r--r--ext/simplexml/tests/profile09.phpt19
-rw-r--r--ext/simplexml/tests/profile10.phpt25
-rw-r--r--ext/simplexml/tests/profile11.phpt35
-rw-r--r--ext/simplexml/tests/profile12.phpt74
-rw-r--r--ext/simplexml/tests/profile13.phpt75
-rw-r--r--ext/simplexml/tests/simplexml_import_dom.phpt22
-rw-r--r--ext/simplexml/tests/simplexml_load_file.phpt32
-rwxr-xr-xext/simplexml/tests/sxe.dtd34
-rwxr-xr-xext/simplexml/tests/sxe.ent1
-rwxr-xr-xext/simplexml/tests/sxe.xml17
-rw-r--r--ext/simplexml/tests/sxe_001.phpt63
-rw-r--r--ext/simplexml/tests/sxe_002.phpt75
-rw-r--r--ext/simplexml/tests/sxe_003.phpt77
-rw-r--r--ext/simplexml/tests/sxe_004.phpt145
-rw-r--r--ext/simplexml/tests/sxe_005.phpt44
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 "&#38;#x00A0;">
+]>
+<root attr='foo&nbsp;bar&nbsp;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;amp; def" a2="abc &amp;amp; def" a3="abc &amp; def" a4="abc &amp; 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 &#38; b';
+print $xml_element->node1."\n";
+$xml_element->node1 = 'a &#38; b';
+print $xml_element->node1."\n";
+$xml_element->addChild('node2','a &#38; b');
+print $xml_element->node2."\n";
+$xml_element->node2 = 'a & b';
+print $xml_element->node2."\n";
+
+print $xml_element->asXML();
+
+?>
+===DONE===
+--EXPECTF--
+a &#38; b
+a &#38; b
+a & b
+a & b
+<?xml version="1.0"?>
+<root><node1>a &amp;#38; b</node1><node2>a &amp; 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===