dmitry Thu Sep 27 10:02:04 2007 UTC
Modified files:
/php-src/ext/soap php_encoding.c
/php-src/ext/soap/tests any.phpt
Log:
Improved ext/soap to support element names in context of XMLShema's <any>
http://cvs.php.net/viewvc.cgi/php-src/ext/soap/php_encoding.c?r1=1.162&r2=1.163&diff_format=u
Index: php-src/ext/soap/php_encoding.c
diff -u php-src/ext/soap/php_encoding.c:1.162
php-src/ext/soap/php_encoding.c:1.163
--- php-src/ext/soap/php_encoding.c:1.162 Fri Aug 31 08:07:46 2007
+++ php-src/ext/soap/php_encoding.c Thu Sep 27 10:02:04 2007
@@ -17,7 +17,7 @@
| Dmitry Stogov <[EMAIL PROTECTED]> |
+----------------------------------------------------------------------+
*/
-/* $Id: php_encoding.c,v 1.162 2007/08/31 08:07:46 dmitry Exp $ */
+/* $Id: php_encoding.c,v 1.163 2007/09/27 10:02:04 dmitry Exp $ */
#include <time.h>
@@ -1182,44 +1182,84 @@
static void model_to_zval_any(zval *ret, xmlNodePtr node TSRMLS_DC)
{
zval* any = NULL;
+ char* name = NULL;
while (node != NULL) {
if (get_zval_property(ret, (char*)node->name TSRMLS_CC) ==
NULL) {
zval* val = master_to_zval(get_conversion(XSD_ANYXML),
node);
- if (get_attribute_ex(node->properties,"type",
XSI_NAMESPACE) == NULL &&
- (Z_TYPE_P(val) == IS_STRING || Z_TYPE_P(val) ==
IS_UNICODE)) {
- while (node->next != NULL &&
- get_zval_property(ret,
(char*)node->next->name TSRMLS_CC) == NULL &&
-
get_attribute_ex(node->next->properties,"type", XSI_NAMESPACE) == NULL) {
+
+ if (any && Z_TYPE_P(any) != IS_ARRAY) {
+ /* Convert into array */
+ zval *arr;
+
+ MAKE_STD_ZVAL(arr);
+ array_init(arr);
+ if (name) {
+ add_rt_assoc_zval(arr, name, any);
+ } else {
+ add_next_index_zval(arr, any);
+ }
+ any = arr;
+ }
+
+ if ((Z_TYPE_P(val) == IS_STRING && *Z_STRVAL_P(val) ==
'<') ||
+ (Z_TYPE_P(val) == IS_UNICODE &&
*Z_USTRVAL_P(val) == '<')) {
+ name = NULL;
+ while (node->next != NULL) {
zval* val2 =
master_to_zval(get_conversion(XSD_ANYXML), node->next);
- if (Z_TYPE_P(val2) != IS_STRING &&
Z_TYPE_P(val2) != IS_UNICODE) {
+ if ((Z_TYPE_P(val2) != IS_STRING ||
*Z_STRVAL_P(val) != '<') &&
+ (Z_TYPE_P(val2) != IS_UNICODE ||
*Z_USTRVAL_P(val) != '<')) {
break;
}
add_string_to_string(val, val, val2);
zval_ptr_dtor(&val2);
node = node->next;
}
+ } else {
+ name = (char*)node->name;
}
+
if (any == NULL) {
- any = val;
- } else {
- if (Z_TYPE_P(any) != IS_ARRAY) {
+ if (name) {
/* Convert into array */
zval *arr;
MAKE_STD_ZVAL(arr);
array_init(arr);
- add_next_index_zval(arr, any);
+ add_rt_assoc_zval(arr, name, val);
any = arr;
+ name = NULL;
+ } else {
+ any = val;
}
+ } else {
/* Add array element */
- add_next_index_zval(any, val);
+ if (name) {
+ zval **el;
+ if (zend_rt_hash_find(Z_ARRVAL_P(any),
name, strlen(name)+1, (void**)&el) == SUCCESS) {
+ if (Z_TYPE_PP(el) != IS_ARRAY) {
+ /* Convert into array */
+ zval *arr;
+
+ MAKE_STD_ZVAL(arr);
+ array_init(arr);
+
add_next_index_zval(arr, *el);
+ *el = arr;
+ }
+ add_next_index_zval(*el, val);
+ } else {
+ add_rt_assoc_zval(any, name,
val);
+ }
+ } else {
+ add_next_index_zval(any, val);
+ }
+ name = NULL;
}
}
node = node->next;
}
if (any) {
- set_zval_property(ret, "any", any TSRMLS_CC);
+ set_zval_property(ret, name ? name : "any", any TSRMLS_CC);
}
}
@@ -2991,6 +3031,25 @@
zval *ret;
TSRMLS_FETCH();
+ if (SOAP_GLOBAL(sdl) && SOAP_GLOBAL(sdl)->elements && data->name) {
+ smart_str nscat = {0};
+ sdlTypePtr *sdl_type;
+
+ if (data->ns && data->ns->href) {
+ smart_str_appends(&nscat, (char*)data->ns->href);
+ smart_str_appendc(&nscat, ':');
+ }
+ smart_str_appends(&nscat, (char*)data->name);
+ smart_str_0(&nscat);
+
+ if (zend_hash_find(SOAP_GLOBAL(sdl)->elements, nscat.c,
nscat.len+1, (void **)&sdl_type) == SUCCESS &&
+ (*sdl_type)->encode) {
+ smart_str_free(&nscat);
+ return master_to_zval_int((*sdl_type)->encode, data);
+ }
+ smart_str_free(&nscat);
+ }
+
buf = xmlBufferCreate();
xmlNodeDump(buf, NULL, data, 0, 0);
MAKE_STD_ZVAL(ret);
@@ -3001,8 +3060,38 @@
static xmlNodePtr to_xml_any(encodeTypePtr type, zval *data, int style,
xmlNodePtr parent)
{
- xmlNodePtr ret;
+ xmlNodePtr ret = NULL;
+
+ if (Z_TYPE_P(data) == IS_ARRAY) {
+ HashPosition pos;
+ zval **el;
+ encodePtr enc = get_conversion(XSD_ANYXML);
+ char *name;
+ uint name_len;
+ ulong idx;
+ TSRMLS_FETCH();
+ for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(data),
&pos);
+ zend_hash_get_current_data_ex(Z_ARRVAL_P(data), (void **)
&el, &pos) == SUCCESS;
+ zend_hash_move_forward_ex(Z_ARRVAL_P(data), &pos)) {
+ ret = master_to_xml(enc, *el, style, parent);
+ if (ret &&
+ ret->name != xmlStringTextNoenc) {
+ int utype =
zend_hash_get_current_key_ex(Z_ARRVAL_P(data), &name, &name_len, &idx, 0, &pos);
+
+ if (utype == HASH_KEY_IS_STRING) {
+ xmlNodeSetName(ret, BAD_CAST(name));
+ } else if (utype == HASH_KEY_IS_UNICODE) {
+ zstr uname;
+
+ uname.s = soap_encode_string_ex(IS_UNICODE,
ZSTR(name), name_len TSRMLS_CC);
+ xmlNodeSetName(ret, BAD_CAST(uname.s));
+ efree(uname.s);
+ }
+ }
+ }
+ return ret;
+ }
if (Z_TYPE_P(data) == IS_STRING) {
ret = xmlNewTextLen(BAD_CAST(Z_STRVAL_P(data)),
Z_STRLEN_P(data));
} else {
http://cvs.php.net/viewvc.cgi/php-src/ext/soap/tests/any.phpt?r1=1.2&r2=1.3&diff_format=u
Index: php-src/ext/soap/tests/any.phpt
diff -u php-src/ext/soap/tests/any.phpt:1.2 php-src/ext/soap/tests/any.phpt:1.3
--- php-src/ext/soap/tests/any.phpt:1.2 Thu Jul 13 16:47:25 2006
+++ php-src/ext/soap/tests/any.phpt Thu Sep 27 10:02:04 2007
@@ -17,9 +17,9 @@
global $g;
$g = $x;
- $struct = $x->inputAny->any;
+ $struct = $x->inputAny->any["SOAPComplexType"];
if ($struct instanceof SOAPComplexType) {
- return array("return" => array("any" => new SoapVar($struct,
SOAP_ENC_OBJECT, "SOAPComplexType", "http://soapinterop.org/xsd",
"SOAPComplexType", "http://soapinterop.org/")));
+ return array("return" => array("any" =>
array("SOAPComplexType"=>new SoapVar($struct, SOAP_ENC_OBJECT,
"SOAPComplexType", "http://soapinterop.org/xsd", "SOAPComplexType",
"http://soapinterop.org/"))));
} else {
return "?";
}
@@ -57,13 +57,16 @@
["inputAny"]=>
object(stdClass)#6 (1) {
["any"]=>
- object(SOAPComplexType)#7 (3) {
- ["varInt"]=>
- int(34)
- ["varString"]=>
- string(3) "arg"
- ["varFloat"]=>
- float(325.325)
+ array(1) {
+ ["SOAPComplexType"]=>
+ object(SOAPComplexType)#7 (3) {
+ ["varInt"]=>
+ int(34)
+ ["varString"]=>
+ string(3) "arg"
+ ["varFloat"]=>
+ float(325.325)
+ }
}
}
}
@@ -71,13 +74,16 @@
["return"]=>
object(stdClass)#9 (1) {
["any"]=>
- object(SOAPComplexType)#10 (3) {
- ["varInt"]=>
- int(34)
- ["varString"]=>
- string(3) "arg"
- ["varFloat"]=>
- float(325.325)
+ array(1) {
+ ["SOAPComplexType"]=>
+ object(SOAPComplexType)#10 (3) {
+ ["varInt"]=>
+ int(34)
+ ["varString"]=>
+ string(3) "arg"
+ ["varFloat"]=>
+ float(325.325)
+ }
}
}
}
@@ -86,13 +92,16 @@
[u"inputAny"]=>
object(stdClass)#6 (1) {
[u"any"]=>
- object(SOAPComplexType)#7 (3) {
- [u"varInt"]=>
- int(34)
- [u"varString"]=>
- unicode(3) "arg"
- [u"varFloat"]=>
- float(325.325)
+ array(1) {
+ [u"SOAPComplexType"]=>
+ object(SOAPComplexType)#7 (3) {
+ [u"varInt"]=>
+ int(34)
+ [u"varString"]=>
+ unicode(3) "arg"
+ [u"varFloat"]=>
+ float(325.325)
+ }
}
}
}
@@ -100,13 +109,16 @@
[u"return"]=>
object(stdClass)#9 (1) {
[u"any"]=>
- object(SOAPComplexType)#10 (3) {
- [u"varInt"]=>
- int(34)
- [u"varString"]=>
- unicode(3) "arg"
- [u"varFloat"]=>
- float(325.325)
+ array(1) {
+ [u"SOAPComplexType"]=>
+ object(SOAPComplexType)#10 (3) {
+ [u"varInt"]=>
+ int(34)
+ [u"varString"]=>
+ unicode(3) "arg"
+ [u"varFloat"]=>
+ float(325.325)
+ }
}
}
}
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php