mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
Several improvements to the simplexml_element object:
- Allow to use it as an instance of Iterator - Prepareto use it as a normal object, including spcialization
This commit is contained in:
parent
ceaddf238b
commit
fc117add30
4 changed files with 236 additions and 119 deletions
|
@ -64,6 +64,12 @@ typedef struct {
|
||||||
HashTable *properties;
|
HashTable *properties;
|
||||||
simplexml_nsmap *nsmapptr;
|
simplexml_nsmap *nsmapptr;
|
||||||
xmlXPathContextPtr xpath;
|
xmlXPathContextPtr xpath;
|
||||||
|
struct {
|
||||||
|
xmlNodePtr node;
|
||||||
|
char *name;
|
||||||
|
int namelen;
|
||||||
|
zval *data;
|
||||||
|
} iter;
|
||||||
} php_sxe_object;
|
} php_sxe_object;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -30,8 +30,17 @@
|
||||||
#include "ext/standard/info.h"
|
#include "ext/standard/info.h"
|
||||||
#include "php_simplexml.h"
|
#include "php_simplexml.h"
|
||||||
|
|
||||||
|
#if HAVE_SPL
|
||||||
|
#include "ext/spl/spl_iterators.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
zend_class_entry *sxe_class_entry;
|
zend_class_entry *sxe_class_entry;
|
||||||
|
|
||||||
|
#define SXE_ME(func, arg_info, flags) PHP_ME(simplexml_element, func, arg_info, flags)
|
||||||
|
|
||||||
|
#define SXE_METHOD(func) PHP_METHOD(simplexml_element, func)
|
||||||
|
|
||||||
#define SKIP_TEXT(__p) \
|
#define SKIP_TEXT(__p) \
|
||||||
if ((__p)->type == XML_TEXT_NODE) { \
|
if ((__p)->type == XML_TEXT_NODE) { \
|
||||||
goto next_iter; \
|
goto next_iter; \
|
||||||
|
@ -51,8 +60,7 @@ php_sxe_fetch_object(zval *object TSRMLS_DC)
|
||||||
|
|
||||||
/* {{{ _node_as_zval()
|
/* {{{ _node_as_zval()
|
||||||
*/
|
*/
|
||||||
static void
|
static void _node_as_zval(php_sxe_object *sxe, xmlNodePtr node, zval *value TSRMLS_DC)
|
||||||
_node_as_zval(php_sxe_object *sxe, xmlNodePtr node, zval *value TSRMLS_DC)
|
|
||||||
{
|
{
|
||||||
php_sxe_object *subnode;
|
php_sxe_object *subnode;
|
||||||
|
|
||||||
|
@ -118,8 +126,7 @@ match_ns(php_sxe_object *sxe, xmlNodePtr node, xmlChar *name)
|
||||||
|
|
||||||
/* {{{ sxe_prop_dim_read()
|
/* {{{ sxe_prop_dim_read()
|
||||||
*/
|
*/
|
||||||
static zval *
|
static zval * sxe_prop_dim_read(zval *object, zval *member, zend_bool elements, zend_bool attribs, zend_bool silent TSRMLS_DC)
|
||||||
sxe_prop_dim_read(zval *object, zval *member, zend_bool elements, zend_bool attribs, zend_bool silent TSRMLS_DC)
|
|
||||||
{
|
{
|
||||||
zval *return_value;
|
zval *return_value;
|
||||||
zval *value = NULL;
|
zval *value = NULL;
|
||||||
|
@ -224,8 +231,7 @@ next_iter:
|
||||||
|
|
||||||
/* {{{ sxe_property_read()
|
/* {{{ sxe_property_read()
|
||||||
*/
|
*/
|
||||||
static zval *
|
static zval * sxe_property_read(zval *object, zval *member, zend_bool silent TSRMLS_DC)
|
||||||
sxe_property_read(zval *object, zval *member, zend_bool silent TSRMLS_DC)
|
|
||||||
{
|
{
|
||||||
return sxe_prop_dim_read(object, member, 1, 0, silent TSRMLS_CC);
|
return sxe_prop_dim_read(object, member, 1, 0, silent TSRMLS_CC);
|
||||||
}
|
}
|
||||||
|
@ -233,7 +239,7 @@ sxe_property_read(zval *object, zval *member, zend_bool silent TSRMLS_DC)
|
||||||
|
|
||||||
/* {{{ sxe_dimension_read()
|
/* {{{ sxe_dimension_read()
|
||||||
*/
|
*/
|
||||||
static zval *sxe_dimension_read(zval *object, zval *offset TSRMLS_DC)
|
static zval * sxe_dimension_read(zval *object, zval *offset TSRMLS_DC)
|
||||||
{
|
{
|
||||||
return sxe_prop_dim_read(object, offset, 0, 1, 0 TSRMLS_CC);
|
return sxe_prop_dim_read(object, offset, 0, 1, 0 TSRMLS_CC);
|
||||||
}
|
}
|
||||||
|
@ -641,10 +647,9 @@ sxe_method_get(zval *object, char *name, int len TSRMLS_DC)
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ simplexml_ce_xpath_search()
|
/* {{{ xsearch()
|
||||||
*/
|
*/
|
||||||
static void
|
SXE_METHOD(xsearch)
|
||||||
simplexml_ce_xpath_search(INTERNAL_FUNCTION_PARAMETERS)
|
|
||||||
{
|
{
|
||||||
php_sxe_object *sxe;
|
php_sxe_object *sxe;
|
||||||
zval *value;
|
zval *value;
|
||||||
|
@ -694,8 +699,7 @@ simplexml_ce_xpath_search(INTERNAL_FUNCTION_PARAMETERS)
|
||||||
_node_as_zval(sxe, result->nodeTab[i], value TSRMLS_CC);
|
_node_as_zval(sxe, result->nodeTab[i], value TSRMLS_CC);
|
||||||
}
|
}
|
||||||
add_next_index_zval(return_value, value);
|
add_next_index_zval(return_value, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
@ -775,12 +779,26 @@ simplexml_ce_schema_validate(INTERNAL_FUNCTION_PARAMETERS, int type)
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
/* {{{ validate_schema_file
|
||||||
|
*/
|
||||||
|
SXE_METHOD(validate_schema_file)
|
||||||
|
{
|
||||||
|
simplexml_ce_schema_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, SCHEMA_FILE);
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
|
/* {{{ validate_schema_buffer
|
||||||
|
*/
|
||||||
|
SXE_METHOD(validate_schema_buffer)
|
||||||
|
{
|
||||||
|
simplexml_ce_schema_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, SCHEMA_BLOB);
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* {{{ simplexml_ce_register_ns()
|
/* {{{ simplexml_ce_register_ns()
|
||||||
*/
|
*/
|
||||||
static void
|
SXE_METHOD(register_ns)
|
||||||
simplexml_ce_register_ns(INTERNAL_FUNCTION_PARAMETERS)
|
|
||||||
{
|
{
|
||||||
php_sxe_object *sxe;
|
php_sxe_object *sxe;
|
||||||
char *nsname;
|
char *nsname;
|
||||||
|
@ -800,8 +818,7 @@ simplexml_ce_register_ns(INTERNAL_FUNCTION_PARAMETERS)
|
||||||
|
|
||||||
/* {{{ simplexml_ce_to_xml_string()
|
/* {{{ simplexml_ce_to_xml_string()
|
||||||
*/
|
*/
|
||||||
static void
|
SXE_METHOD(to_xml_string)
|
||||||
simplexml_ce_to_xml_string(INTERNAL_FUNCTION_PARAMETERS)
|
|
||||||
{
|
{
|
||||||
php_sxe_object *sxe;
|
php_sxe_object *sxe;
|
||||||
xmlChar *strval;
|
xmlChar *strval;
|
||||||
|
@ -822,8 +839,7 @@ simplexml_ce_to_xml_string(INTERNAL_FUNCTION_PARAMETERS)
|
||||||
|
|
||||||
/* {{{ simplexml_ce_to_xml_file()
|
/* {{{ simplexml_ce_to_xml_file()
|
||||||
*/
|
*/
|
||||||
static void
|
SXE_METHOD(to_xml_file)
|
||||||
simplexml_ce_to_xml_file(INTERNAL_FUNCTION_PARAMETERS)
|
|
||||||
{
|
{
|
||||||
php_sxe_object *sxe;
|
php_sxe_object *sxe;
|
||||||
char *filename;
|
char *filename;
|
||||||
|
@ -841,54 +857,6 @@ simplexml_ce_to_xml_file(INTERNAL_FUNCTION_PARAMETERS)
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ sxe_call_method()
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
sxe_call_method(char *method, INTERNAL_FUNCTION_PARAMETERS)
|
|
||||||
{
|
|
||||||
if (!strcmp(method, "xsearch")) {
|
|
||||||
simplexml_ce_xpath_search(INTERNAL_FUNCTION_PARAM_PASSTHRU);
|
|
||||||
#ifdef LIBXML_SCHEMAS_ENABLED
|
|
||||||
} else if (!strcmp(method, "validate_schema_file")) {
|
|
||||||
simplexml_ce_schema_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, SCHEMA_FILE);
|
|
||||||
} else if (!strcmp(method, "validate_schema_buffer")) {
|
|
||||||
simplexml_ce_schema_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, SCHEMA_BLOB);
|
|
||||||
#endif
|
|
||||||
} else if (!strcmp(method, "register_ns")) {
|
|
||||||
simplexml_ce_register_ns(INTERNAL_FUNCTION_PARAM_PASSTHRU);
|
|
||||||
} else if (!strcmp(method, "to_xml")) {
|
|
||||||
simplexml_ce_to_xml_string(INTERNAL_FUNCTION_PARAM_PASSTHRU);
|
|
||||||
} else if (!strcmp(method, "to_xml_file")) {
|
|
||||||
simplexml_ce_to_xml_file(INTERNAL_FUNCTION_PARAM_PASSTHRU);
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
/* }}} */
|
|
||||||
|
|
||||||
/* {{{ sxe_class_entry_get()
|
|
||||||
*/
|
|
||||||
static zend_class_entry *
|
|
||||||
sxe_class_entry_get(zval *object TSRMLS_DC)
|
|
||||||
{
|
|
||||||
return sxe_class_entry;
|
|
||||||
}
|
|
||||||
/* }}} */
|
|
||||||
|
|
||||||
/* {{{ sxe_class_name_get()
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
sxe_class_name_get(zval *object, char **class_name, zend_uint *class_name_len, int parent TSRMLS_DC)
|
|
||||||
{
|
|
||||||
*class_name = estrdup("simplexml_element");
|
|
||||||
*class_name_len = sizeof("simplexml_element")-1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/* }}} */
|
|
||||||
|
|
||||||
/* {{{ cast_object()
|
/* {{{ cast_object()
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
|
@ -1001,10 +969,10 @@ static zend_object_handlers sxe_object_handlers = {
|
||||||
sxe_dimension_delete,
|
sxe_dimension_delete,
|
||||||
sxe_properties_get,
|
sxe_properties_get,
|
||||||
sxe_method_get,
|
sxe_method_get,
|
||||||
sxe_call_method,
|
NULL, /* zend_get_std_object_handlers()->get_method,*/
|
||||||
sxe_constructor_get,
|
sxe_constructor_get,
|
||||||
sxe_class_entry_get,
|
NULL, /* zend_get_std_object_handlers()->get_class_entry,*/
|
||||||
sxe_class_name_get,
|
NULL, /* zend_get_std_object_handlers()->get_class_name,*/
|
||||||
sxe_objects_compare,
|
sxe_objects_compare,
|
||||||
sxe_object_cast
|
sxe_object_cast
|
||||||
};
|
};
|
||||||
|
@ -1049,8 +1017,7 @@ _free_ns_entry(void *p, xmlChar *data)
|
||||||
|
|
||||||
/* {{{ sxe_object_dtor()
|
/* {{{ sxe_object_dtor()
|
||||||
*/
|
*/
|
||||||
static void
|
static void sxe_object_dtor(void *object, zend_object_handle handle TSRMLS_DC)
|
||||||
sxe_object_dtor(void *object, zend_object_handle handle TSRMLS_DC)
|
|
||||||
{
|
{
|
||||||
php_sxe_object *sxe;
|
php_sxe_object *sxe;
|
||||||
|
|
||||||
|
@ -1059,6 +1026,10 @@ sxe_object_dtor(void *object, zend_object_handle handle TSRMLS_DC)
|
||||||
zend_hash_destroy(sxe->zo.properties);
|
zend_hash_destroy(sxe->zo.properties);
|
||||||
FREE_HASHTABLE(sxe->zo.properties);
|
FREE_HASHTABLE(sxe->zo.properties);
|
||||||
|
|
||||||
|
if (sxe->iter.data) {
|
||||||
|
zval_ptr_dtor(&sxe->iter.data);
|
||||||
|
}
|
||||||
|
|
||||||
php_libxml_node_decrement_resource((php_libxml_node_object *)sxe TSRMLS_CC);
|
php_libxml_node_decrement_resource((php_libxml_node_object *)sxe TSRMLS_CC);
|
||||||
|
|
||||||
if (--sxe->nsmapptr->refcount == 0) {
|
if (--sxe->nsmapptr->refcount == 0) {
|
||||||
|
@ -1074,27 +1045,19 @@ sxe_object_dtor(void *object, zend_object_handle handle TSRMLS_DC)
|
||||||
zend_hash_destroy(sxe->properties);
|
zend_hash_destroy(sxe->properties);
|
||||||
FREE_HASHTABLE(sxe->properties);
|
FREE_HASHTABLE(sxe->properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
efree(object);
|
efree(object);
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ php_sxe_object_new()
|
/* {{{ php_sxe_object_new()
|
||||||
*/
|
*/
|
||||||
static php_sxe_object *
|
static php_sxe_object* php_sxe_object_new(TSRMLS_D)
|
||||||
php_sxe_object_new(TSRMLS_D)
|
|
||||||
{
|
{
|
||||||
php_sxe_object *intern;
|
php_sxe_object *intern;
|
||||||
|
|
||||||
intern = ecalloc(1, sizeof(php_sxe_object));
|
intern = ecalloc(1, sizeof(php_sxe_object));
|
||||||
intern->zo.ce = sxe_class_entry;
|
intern->zo.ce = sxe_class_entry;
|
||||||
intern->zo.in_get = 0;
|
|
||||||
intern->zo.in_set = 0;
|
|
||||||
intern->node = NULL;
|
|
||||||
intern->document = NULL;
|
|
||||||
intern->nsmapptr = NULL;
|
|
||||||
intern->xpath = NULL;
|
|
||||||
intern->properties = NULL;
|
|
||||||
|
|
||||||
ALLOC_HASHTABLE(intern->zo.properties);
|
ALLOC_HASHTABLE(intern->zo.properties);
|
||||||
zend_hash_init(intern->zo.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
|
zend_hash_init(intern->zo.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
|
||||||
|
@ -1192,10 +1155,6 @@ PHP_FUNCTION(simplexml_load_string)
|
||||||
typedef struct {
|
typedef struct {
|
||||||
zend_object_iterator intern;
|
zend_object_iterator intern;
|
||||||
php_sxe_object *sxe;
|
php_sxe_object *sxe;
|
||||||
xmlNodePtr node;
|
|
||||||
char *name;
|
|
||||||
int namelen;
|
|
||||||
zval *data;
|
|
||||||
} php_sxe_iterator;
|
} php_sxe_iterator;
|
||||||
|
|
||||||
static void php_sxe_iterator_dtor(zend_object_iterator *iter TSRMLS_DC);
|
static void php_sxe_iterator_dtor(zend_object_iterator *iter TSRMLS_DC);
|
||||||
|
@ -1203,6 +1162,7 @@ static int php_sxe_iterator_has_more(zend_object_iterator *iter TSRMLS_DC);
|
||||||
static void php_sxe_iterator_current_data(zend_object_iterator *iter, zval ***data 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 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_move_forward(zend_object_iterator *iter TSRMLS_DC);
|
||||||
|
static void php_sxe_iterator_rewind(zend_object_iterator *iter TSRMLS_DC);
|
||||||
|
|
||||||
zend_object_iterator_funcs php_sxe_iterator_funcs = {
|
zend_object_iterator_funcs php_sxe_iterator_funcs = {
|
||||||
php_sxe_iterator_dtor,
|
php_sxe_iterator_dtor,
|
||||||
|
@ -1210,15 +1170,19 @@ zend_object_iterator_funcs php_sxe_iterator_funcs = {
|
||||||
php_sxe_iterator_current_data,
|
php_sxe_iterator_current_data,
|
||||||
php_sxe_iterator_current_key,
|
php_sxe_iterator_current_key,
|
||||||
php_sxe_iterator_move_forward,
|
php_sxe_iterator_move_forward,
|
||||||
NULL
|
php_sxe_iterator_rewind,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void php_sxe_iterator_current(php_sxe_iterator *iterator TSRMLS_DC)
|
static void php_sxe_iterator_current(php_sxe_object *sxe TSRMLS_DC)
|
||||||
{
|
{
|
||||||
xmlNodePtr node;
|
xmlNodePtr node;
|
||||||
|
|
||||||
while (iterator->node) {
|
if (sxe->iter.data) {
|
||||||
node = iterator->node;
|
zval_ptr_dtor(&sxe->iter.data);
|
||||||
|
}
|
||||||
|
ALLOC_INIT_ZVAL(sxe->iter.data);
|
||||||
|
while (sxe->iter.node) {
|
||||||
|
node = sxe->iter.node;
|
||||||
|
|
||||||
SKIP_TEXT(node);
|
SKIP_TEXT(node);
|
||||||
|
|
||||||
|
@ -1230,17 +1194,16 @@ static void php_sxe_iterator_current(php_sxe_iterator *iterator TSRMLS_DC)
|
||||||
}
|
}
|
||||||
} while (0);
|
} while (0);
|
||||||
|
|
||||||
if (!iterator->node->name) {
|
if (!sxe->iter.node->name) {
|
||||||
goto next_iter;
|
goto next_iter;
|
||||||
} else {
|
} else {
|
||||||
iterator->namelen = xmlStrlen(node->name)+1;
|
sxe->iter.namelen = xmlStrlen(node->name)+1;
|
||||||
iterator->name = (char *) node->name;
|
sxe->iter.name = (char *) node->name;
|
||||||
MAKE_STD_ZVAL(iterator->data);
|
_node_as_zval(sxe, node, sxe->iter.data TSRMLS_CC);
|
||||||
_node_as_zval(iterator->sxe, node, iterator->data TSRMLS_CC);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
next_iter:
|
next_iter:
|
||||||
iterator->node = iterator->node->next;
|
sxe->iter.node = sxe->iter.node->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1252,10 +1215,6 @@ zend_object_iterator *php_sxe_get_iterator(zend_class_entry *ce, zval *object TS
|
||||||
iterator->intern.data = (void*)object;
|
iterator->intern.data = (void*)object;
|
||||||
iterator->intern.funcs = &php_sxe_iterator_funcs;
|
iterator->intern.funcs = &php_sxe_iterator_funcs;
|
||||||
iterator->sxe = php_sxe_fetch_object(object TSRMLS_CC);
|
iterator->sxe = php_sxe_fetch_object(object TSRMLS_CC);
|
||||||
GET_NODE(iterator->sxe, iterator->node);
|
|
||||||
iterator->node = iterator->node->children;
|
|
||||||
iterator->data = NULL;
|
|
||||||
php_sxe_iterator_current(iterator TSRMLS_CC);
|
|
||||||
|
|
||||||
return (zend_object_iterator*)iterator;
|
return (zend_object_iterator*)iterator;
|
||||||
}
|
}
|
||||||
|
@ -1266,9 +1225,6 @@ static void php_sxe_iterator_dtor(zend_object_iterator *iter TSRMLS_DC)
|
||||||
|
|
||||||
zval_ptr_dtor((zval**)&iterator->intern.data);
|
zval_ptr_dtor((zval**)&iterator->intern.data);
|
||||||
|
|
||||||
if (iterator->data) {
|
|
||||||
zval_ptr_dtor(&iterator->data);
|
|
||||||
}
|
|
||||||
efree(iterator);
|
efree(iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1276,37 +1232,147 @@ static int php_sxe_iterator_has_more(zend_object_iterator *iter TSRMLS_DC)
|
||||||
{
|
{
|
||||||
php_sxe_iterator *iterator = (php_sxe_iterator *)iter;
|
php_sxe_iterator *iterator = (php_sxe_iterator *)iter;
|
||||||
|
|
||||||
return iterator->node ? SUCCESS : FAILURE;
|
return iterator->sxe->iter.node ? SUCCESS : FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void php_sxe_iterator_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC)
|
static void php_sxe_iterator_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC)
|
||||||
{
|
{
|
||||||
php_sxe_iterator *iterator = (php_sxe_iterator *)iter;
|
php_sxe_iterator *iterator = (php_sxe_iterator *)iter;
|
||||||
|
|
||||||
*data = &iterator->data;
|
*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)
|
static int php_sxe_iterator_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC)
|
||||||
{
|
{
|
||||||
php_sxe_iterator *iterator = (php_sxe_iterator *)iter;
|
php_sxe_iterator *iterator = (php_sxe_iterator *)iter;
|
||||||
|
|
||||||
*str_key = estrndup(iterator->name, iterator->namelen-1);
|
*str_key = estrndup(iterator->sxe->iter.name, iterator->sxe->iter.namelen-1);
|
||||||
*str_key_len = iterator->namelen;
|
*str_key_len = iterator->sxe->iter.namelen;
|
||||||
return HASH_KEY_IS_STRING;
|
return HASH_KEY_IS_STRING;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void php_sxe_iterator_move_forward(zend_object_iterator *iter TSRMLS_DC)
|
static void php_sxe_iterator_move_forward(zend_object_iterator *iter TSRMLS_DC)
|
||||||
{
|
{
|
||||||
php_sxe_iterator *iterator = (php_sxe_iterator *)iter;
|
php_sxe_iterator *iterator = (php_sxe_iterator *)iter;
|
||||||
|
|
||||||
if (iterator->data) {
|
if (iterator->sxe->iter.node) {
|
||||||
zval_ptr_dtor(&iterator->data);
|
iterator->sxe->iter.node = iterator->sxe->iter.node->next;
|
||||||
iterator->data = NULL;
|
|
||||||
}
|
}
|
||||||
iterator->node = iterator->node->next;
|
php_sxe_iterator_current(iterator->sxe TSRMLS_CC);
|
||||||
php_sxe_iterator_current(iterator TSRMLS_CC);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void php_sxe_iterator_rewind(zend_object_iterator *iter TSRMLS_DC)
|
||||||
|
{
|
||||||
|
php_sxe_iterator *iterator = (php_sxe_iterator *)iter;
|
||||||
|
|
||||||
|
GET_NODE(iterator->sxe, iterator->sxe->iter.node);
|
||||||
|
if (iterator->sxe->iter.node) {
|
||||||
|
iterator->sxe->iter.node = iterator->sxe->iter.node->children;
|
||||||
|
}
|
||||||
|
php_sxe_iterator_current(iterator->sxe TSRMLS_CC);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* {{{ rewind()
|
||||||
|
*/
|
||||||
|
SXE_METHOD(rewind)
|
||||||
|
{
|
||||||
|
php_sxe_object *sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
|
||||||
|
|
||||||
|
GET_NODE(sxe, sxe->iter.node);
|
||||||
|
if (sxe->iter.node) {
|
||||||
|
sxe->iter.node = sxe->iter.node->children;
|
||||||
|
}
|
||||||
|
php_sxe_iterator_current(sxe TSRMLS_CC);
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
|
/* {{{ hasMore()
|
||||||
|
*/
|
||||||
|
SXE_METHOD(hasMore)
|
||||||
|
{
|
||||||
|
php_sxe_object *sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
|
||||||
|
|
||||||
|
RETURN_BOOL(sxe->iter.node);
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
|
/* {{{ curent()
|
||||||
|
*/
|
||||||
|
SXE_METHOD(current)
|
||||||
|
{
|
||||||
|
php_sxe_object *sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
|
||||||
|
|
||||||
|
REPLACE_ZVAL_VALUE(&return_value, sxe->iter.data, 1);
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
|
/* {{{ key()
|
||||||
|
*/
|
||||||
|
SXE_METHOD(key)
|
||||||
|
{
|
||||||
|
php_sxe_object *sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
|
||||||
|
|
||||||
|
RETURN_STRINGL(sxe->iter.name, sxe->iter.namelen-1, 1);
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
|
/* {{{ next()
|
||||||
|
*/
|
||||||
|
SXE_METHOD(next)
|
||||||
|
{
|
||||||
|
php_sxe_object *sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
|
||||||
|
|
||||||
|
if (sxe->iter.node) {
|
||||||
|
sxe->iter.node = sxe->iter.node->next;
|
||||||
|
}
|
||||||
|
php_sxe_iterator_current(sxe TSRMLS_CC);
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
|
/* {{{ hasChildren()
|
||||||
|
*/
|
||||||
|
SXE_METHOD(hasChildren)
|
||||||
|
{
|
||||||
|
php_sxe_object *sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
|
||||||
|
php_sxe_object *child = php_sxe_fetch_object(sxe->iter.data TSRMLS_CC);
|
||||||
|
xmlNodePtr node;
|
||||||
|
|
||||||
|
GET_NODE(child, node);
|
||||||
|
if (node) {
|
||||||
|
node = node->children;
|
||||||
|
}
|
||||||
|
while (node) {
|
||||||
|
SKIP_TEXT(node);
|
||||||
|
|
||||||
|
do if (node->ns) {
|
||||||
|
if (node->parent->ns) {
|
||||||
|
if (!xmlStrcmp(node->ns->href, node->parent->ns->href)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (0);
|
||||||
|
if (node->type == XML_ELEMENT_NODE) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
next_iter:
|
||||||
|
node = node->next;
|
||||||
|
}
|
||||||
|
RETURN_BOOL(node ? 1 : 0);
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
|
/* {{{ getChildren()
|
||||||
|
*/
|
||||||
|
SXE_METHOD(getChildren)
|
||||||
|
{
|
||||||
|
php_sxe_object *sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
|
||||||
|
|
||||||
|
// REPLACE_ZVAL_VALUE(&return_value, sxe->iter.data, 0);
|
||||||
|
return_value->type = IS_OBJECT;
|
||||||
|
return_value->value.obj = zend_objects_store_clone_obj(sxe->iter.data TSRMLS_CC);
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ proto simplemxml_element simplexml_import_dom(domNode node)
|
/* {{{ proto simplemxml_element simplexml_import_dom(domNode node)
|
||||||
Get a simplexml_element object from dom to allow for processing */
|
Get a simplexml_element object from dom to allow for processing */
|
||||||
PHP_FUNCTION(simplexml_import_dom)
|
PHP_FUNCTION(simplexml_import_dom)
|
||||||
|
@ -1379,17 +1445,44 @@ zend_module_entry simplexml_module_entry = {
|
||||||
#ifdef COMPILE_DL_SIMPLEXML
|
#ifdef COMPILE_DL_SIMPLEXML
|
||||||
ZEND_GET_MODULE(simplexml)
|
ZEND_GET_MODULE(simplexml)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* the method table */
|
||||||
|
/* each method can have its own parameters and visibility */
|
||||||
|
static zend_function_entry sxe_functions[] = {
|
||||||
|
SXE_ME(register_ns, NULL, ZEND_ACC_PUBLIC)
|
||||||
|
SXE_ME(to_xml_file, NULL, ZEND_ACC_PUBLIC)
|
||||||
|
SXE_ME(to_xml_string, NULL, ZEND_ACC_PUBLIC)
|
||||||
|
#ifdef LIBXML_SCHEMAS_ENABLED
|
||||||
|
SXE_ME(validate_schema_buffer, NULL, ZEND_ACC_PUBLIC)
|
||||||
|
SXE_ME(validate_schema_file, NULL, ZEND_ACC_PUBLIC)
|
||||||
|
#endif
|
||||||
|
SXE_ME(xsearch, NULL, ZEND_ACC_PUBLIC)
|
||||||
|
SXE_ME(rewind, NULL, ZEND_ACC_PUBLIC)
|
||||||
|
SXE_ME(hasMore, NULL, ZEND_ACC_PUBLIC)
|
||||||
|
SXE_ME(current, NULL, ZEND_ACC_PUBLIC)
|
||||||
|
SXE_ME(key, NULL, ZEND_ACC_PUBLIC)
|
||||||
|
SXE_ME(next, NULL, ZEND_ACC_PUBLIC)
|
||||||
|
SXE_ME(hasChildren, NULL, ZEND_ACC_PUBLIC)
|
||||||
|
SXE_ME(getChildren, NULL, ZEND_ACC_PUBLIC)
|
||||||
|
{NULL, NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
/* {{{ PHP_MINIT_FUNCTION(simplexml)
|
/* {{{ PHP_MINIT_FUNCTION(simplexml)
|
||||||
*/
|
*/
|
||||||
PHP_MINIT_FUNCTION(simplexml)
|
PHP_MINIT_FUNCTION(simplexml)
|
||||||
{
|
{
|
||||||
zend_class_entry sxe;
|
zend_class_entry sxe;
|
||||||
|
|
||||||
INIT_CLASS_ENTRY(sxe, "simplexml_element", NULL);
|
INIT_CLASS_ENTRY(sxe, "simplexml_element", sxe_functions);
|
||||||
sxe.create_object = sxe_object_new;
|
sxe.create_object = sxe_object_new;
|
||||||
sxe_class_entry = zend_register_internal_class(&sxe TSRMLS_CC);
|
sxe_class_entry = zend_register_internal_class(&sxe TSRMLS_CC);
|
||||||
|
#if HAVE_SPL
|
||||||
|
zend_class_implements(sxe_class_entry TSRMLS_CC, 1, spl_ce_RecursiveIterator);
|
||||||
|
#endif
|
||||||
sxe_class_entry->get_iterator = php_sxe_get_iterator;
|
sxe_class_entry->get_iterator = php_sxe_get_iterator;
|
||||||
|
sxe_object_handlers.get_method = zend_get_std_object_handlers()->get_method;
|
||||||
|
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;
|
||||||
|
|
||||||
php_libxml_initialize();
|
php_libxml_initialize();
|
||||||
|
|
||||||
|
|
|
@ -12,30 +12,45 @@ foreach($sxe as $name => $data) {
|
||||||
var_dump(trim($data));
|
var_dump(trim($data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
echo "===CLONE===\n";
|
||||||
|
|
||||||
foreach($sxe->__clone() as $name => $data) {
|
foreach($sxe->__clone() as $name => $data) {
|
||||||
var_dump($name);
|
var_dump($name);
|
||||||
var_dump(trim($data));
|
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) {
|
foreach($sxe->elem1 as $name => $data) {
|
||||||
var_dump($name);
|
var_dump($name);
|
||||||
var_dump(trim($data));
|
var_dump(trim($data));
|
||||||
}
|
}
|
||||||
|
|
||||||
echo "===Done===\n";
|
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
===DONE===
|
||||||
--EXPECT--
|
--EXPECT--
|
||||||
string(5) "elem1"
|
string(5) "elem1"
|
||||||
string(10) "Bla bla 1."
|
string(10) "Bla bla 1."
|
||||||
string(6) "elem11"
|
string(6) "elem11"
|
||||||
string(10) "Bla bla 2."
|
string(10) "Bla bla 2."
|
||||||
|
===CLONE===
|
||||||
string(5) "elem1"
|
string(5) "elem1"
|
||||||
string(10) "Bla bla 1."
|
string(10) "Bla bla 1."
|
||||||
string(6) "elem11"
|
string(6) "elem11"
|
||||||
string(10) "Bla bla 2."
|
string(10) "Bla bla 2."
|
||||||
|
===ELEMENT===
|
||||||
|
string(7) "elem111"
|
||||||
|
string(7) "Foo Bar"
|
||||||
|
===COMMENT===
|
||||||
string(7) "comment"
|
string(7) "comment"
|
||||||
string(0) ""
|
string(0) ""
|
||||||
string(5) "elem2"
|
string(5) "elem2"
|
||||||
string(28) "Here we have some text data."
|
string(28) "Here we have some text data."
|
||||||
===Done===
|
===DONE===
|
||||||
|
|
|
@ -20,5 +20,8 @@
|
||||||
</elem1>
|
</elem1>
|
||||||
<elem11 attr2='second'>
|
<elem11 attr2='second'>
|
||||||
Bla bla 2.
|
Bla bla 2.
|
||||||
|
<elem111>
|
||||||
|
Foo Bar
|
||||||
|
</elem111>
|
||||||
</elem11>
|
</elem11>
|
||||||
</sxe>
|
</sxe>
|
Loading…
Add table
Add a link
Reference in a new issue