ID:               41490
 Updated by:       [EMAIL PROTECTED]
 Reported By:      simon at highlyillogical dot org
-Status:           Open
+Status:           Feedback
 Bug Type:         SOAP related
 Operating System: Windows/Linux
 PHP Version:      5.2.2
 Assigned To:      dmitry
 New Comment:

You can access element order using the following trick.

<?php
$wsdl =
"http://zx81.highlyillogical.org/~simon/phpbugtest/phpbugtest.wsdl";;
$options=Array(
                'typemap' => array(array("type_ns"   =>
"http://zx81.highlyillogical.org/~simon/phpbugtest";,
                                         "type_name" => "sentence",
                                         "from_xml"  => "sentence_from_xml"))
                );

function sentence_from_xml($x) {
        return simplexml_load_string($x);
}

$client = new SoapClient($wsdl, $options) ;
$result = $client->bugtest(); 
var_dump($result);
foreach ($result as $key => $val) {
        echo $key . ":" . (string)$val . "\n";
}

Actual result:
--------------
object(SimpleXMLElement)#2 (3) {
  ["other"]=>
  array(3) {
    [0]=>
    string(3) "The"
    [1]=>
    string(2) "is"
    [2]=>
    string(4) "with"
  }
  ["noun"]=>
  array(2) {
    [0]=>
    string(3) "cat"
    [1]=>
    string(6) "string"
  }
  ["verb"]=>
  string(7) "playing"
}
other:The
noun:cat
other:is
verb:playing
other:with
noun:string



Previous Comments:
------------------------------------------------------------------------

[2007-06-14 09:58:27] simon at highlyillogical dot org

In practice, that's not possible. The 'words' example is a
much-simplified example of what I want to happen. In reality my document
is a sequence of objects of different types, but must remain in the
correct order.

Think of an XHTML document. It's valid XML and could theoretically be
used in a similar way. However, in such a document you've got no idea
whether a <p> element, a <ul> element, a <div>, a <form>, or a <table>
is coming next... But they do have to have the order retained. If you
globbed all of the paragraps together, with all of the unordered lists
after, you'd end up with something that didn't make much sense.

In fact, if you look at the schema for XHTML
(http://www.w3.org/TR/xhtml1-schema/#xhtml1-strict) you can see that it
uses exactly this mechanism (xs:choice maxOccurs="unbounded") in order
to implement this. (See the "Block" complexType) -- So, if you want to
parse soap messages with an XHTML payload correctly, a solution to this
problem needs to be found.

------------------------------------------------------------------------

[2007-06-14 07:27:11] [EMAIL PROTECTED]

I don's see a way to fix this. PHP is not able to keep several elemtns
with the same names in object or array. So it is not possible to keep
order of elements with different names.

You can probaly change WSDL to have a sequence of 'words', where each
word is an element defined as extension of type 'string' with
'part_of_speach' attribute. So you'll have to pass something like this:

<sentence>
  <word part_of_speach="other">The</word>
  <word part_of_speach="noun">cat</word>
  <word part_of_speach="other">is</word>
  <word part_of_speach="verb">playing</word>
  <word part_of_speach="other">with</word>
  <word part_of_speach="noun">string</word>
</sentence>


------------------------------------------------------------------------

[2007-05-24 13:36:13] simon at highlyillogical dot org

Description:
------------
When the PHP soap client parses a SOAP response that contains multiple
recurrences of an <xsd:choice maxOccurs="unbounded"> element, the
ordering of elements can be lost, as the results are grouped by element
type.

For example, take the following complex type:
<xsd:complexType name="sentence">
  <xsd:choice maxOccurs="unbounded">
    <xsd element name="noun" type="xsd:string" />
    <xsd element name="verb" type="xsd:string" />
    <xsd element name="other" type="xsd:string" />
  </xsd:choice>
</xsd:type>

This type can describe a sentence, with one element per word. An
example sentence might be:
<sentence>
  <other>The</other>
  <noun>cat</noun>
  <other>is</other>
  <verb>playing</verb>
  <other>with</other>
  <noun>string</noun>
</sentence>

When PHP parses this, it groups the elements by type. Thus, a sentence
which reads "The cat is playing with string", is mangled to read "cat
string playing The is with"

I've posted a wsdl to demonstrate the problem at:
http://zx81.highlyillogical.org/~simon/phpbugtest/phpbugtest.wsdl

A valid XML response similar to the case above is at:
http://zx81.highlyillogical.org/~simon/phpbugtest/bugtest.xml

To reproduce the problem, simply call the bugtest operation on the
above wsdl. It will always return the above xml response.

Reproduce code:
---------------
$client = new SoapClient (
"http://zx81.highlyillogical.org/~simon/phpbugtest/phpbugtest.wsdl"; ) ;

// we're just hitting an XML file, so we don't care about the input
$result = $client->bugtest ( ) ; 

var_dump ( $result ) ;

Expected result:
----------------
An output with the resulting objects are presented in the order in
which they occurred in the document.

Actual result:
--------------
object(stdClass)#2 (3) {
  ["noun"]=>
  array(2) {
    [0]=>
    string(3) "cat"
    [1]=>
    string(6) "string"
  }
  ["verb"]=>
  string(7) "playing"
  ["other"]=>
  array(3) {
    [0]=>
    string(3) "The"
    [1]=>
    string(2) "is"
    [2]=>
    string(4) "with"
  }
}


------------------------------------------------------------------------


-- 
Edit this bug report at http://bugs.php.net/?id=41490&edit=1

Reply via email to