PEAR is archived and read-only

This mirror preserves historical PEAR package releases and metadata so existing references remain available.

Home » Web Services » SOAP » Bug #2996

XML Parsing fails to retrieve attributes

Details

Request #2996XML Parsing fails to retrieve attributes
Submitted2004-12-20 19:23 UTC
Fromwhelan at nexserver dot com
StatusWont fix
PackageSOAP
PHP Version4.3.7
OSWindows 2000/XP
Roadmaps(Not assigned)

Comments

[2004-12-20 19:23 UTC] whelan at nexserver dot com

Description:
------------
When making a call to a SOAP server, rather than resulting in an XML doc SOAP automatically parses this doc into a serialized object. This would be great if it would return everything from the original doc, but unfortunately it misses any xml attributes produced in the document. And there is also no way to get the original XML to retrieve these attributes, they are simply lost along the way.

Reproduce code:
---------------
If for instance the following xml is returned:

<Skills>
<Skill category="MED-CERT">
<SkillName>ada</SkillName>
</Skill>
<Skill category="IT-LANG">
<SkillName>java</SkillName>
</Skill>
<Skill category="IT-LANG">
<SkillName>php</SkillName>
</Skill>
</Skills>

Expected result:
----------------
We should expect the following:

[Skills] => Array
(
[0]['category'] => MED-CERT
[0]['skill'] => stdClass Object
(
[SkillName] => ada
)
[0]['category'] => IT-LANG
[0]['skill'] => stdClass Object
(
[SkillName] => java
)
[0]['category'] => IT-LANG
[0]['skill'] => stdClass Object
(
[SkillName] => php
)
)

-OR-

[Skills] => Array
(
[0] => stdClass Object
(
[category] => MED-CERT
[SkillName] => ada
)
[1] => stdClass Object
(
[category] => IT-LANG
[SkillName] => java
)
[2] => stdClass Object
(
[category] => IT-LANG
[SkillName] => php
)
)

Actual result:
--------------
But what we get is:

[Skills] => Array
(
[0] => stdClass Object
(
[SkillName] => ada
)
[1] => stdClass Object
(
[SkillName] => java
)
[2] => stdClass Object
(
[SkillName] => php
)
)

Yes, we lose the category attribute and have no way of retrieving it.

[2004-12-21 22:01 UTC] whelan at nexserver dot com

It appears the attributes are being lost in the _decodeResponse method in Client.php. Still working on a solution.

[2005-11-01 15:55 UTC] martin at malditainternet dot com

usage:
$client->decode_object=true;
$client->call(blah)

--- SOAP_orig/Base.php 2005-11-01 11:43:06.000000000 -0300
+++ SOAP_miop/Base.php 2005-11-01 11:44:12.000000000 -0300
@@ -369,6 +369,9 @@
var $_auto_translation = false;
var $_type_translation = array();

+ // Should _decode() (and call()) return full soap objects instead just the value? (Fixes bug 2996)
+ var $decode_object=false;
+
/**
* Constructor.
*
@@ -969,9 +972,21 @@
}

if ($this->_isBase64Type($soapval->type)) {
- return base64_decode($soapval->value);
+ if (!empty($this->decode_object)){
+ $ret=array(base64_decode($soapval->value),$soapval);
+ return $ret;
+ }else{
+ $ret=base64_decode($soapval->value);
+ return $ret;
+ }
+
} else {
- return $soapval->value;
+ if (!empty($this->decode_object)){
+ $ret=array($soapval->value,$soapval);
+ return $ret;
+ }else{
+ return $soapval->value;
+ }
}
}

[2006-08-01 07:35 UTC] jbradler at eformation dot de

Following bugfix will work with arrays of soap values also. Additionally it will save attributes like a value by using the name of this attribute. This bugfix will also increase the nesting of your resulting array/objects. So use it permanently or leave it. An enable/disable feature of this bugfix is not a good idea.

--- Base.php 2006-08-01 09:21:56.000000000 +0200
+++ Base_.php 2006-08-01 09:23:58.000000000 +0200
@@ -912,6 +912,12 @@
'__set_attribute'),
array($key, $value));
}
+ } else {
+ foreach ($soapval->attributes as $key => $value) {
+ if ($soapval->name == $key)
+ $key .= '_';
+ $return->$key = $value;
+ }
}
} else {
if ($soapval->arrayType && $this->_isSoapValue($item)) {
@@ -952,11 +958,32 @@
$this->_typemap[SOAP_XML_SCHEMA_VERSION][$soapval->type]);
}

- if ($this->_isBase64Type($soapval->type)) {
- return base64_decode($soapval->value);
- } else {
- return $soapval->value;
- }
+
+ // Fixes bug 2996
+ $valueName = $soapval->name;
+ $return = & new $this->_defaultObjectClassname;
+ // set value
+ if ($this->_isBase64Type($soapval->type)) {
+ $return->$valueName = base64_decode($soapval->value);
+ } else {
+ $return->$valueName = $soapval->value;
+ }
+ // Set the attributes as members in the class.
+ if (method_exists($return, '__set_attribute')) {
+ foreach ($soapval->attributes as $key => $value) {
+ call_user_func_array(array(&$return,
+ '__set_attribute'),
+ array($key, $value));
+ }
+ } else {
+ foreach ($soapval->attributes as $key => $value) {
+ if ($soapval->name == $key)
+ $key .= '_';
+ $return->$key = $value;
+ }
+ }
+
+ return $return;
}

/**