Jump to content

Archived

This topic is now archived and is closed to further replies.

phpian

[SOLVED] php Soap Client - Node Attributes

Recommended Posts

Hi there,

 

Does anybody know how to include attriubutes when calling a .net webservice function from php?

 

a normal function would go like this:

 

$client = new SoapClient(wsdl, array('trace' => 1,  'encoding' => 'UTF-8', 'soap_version' => SOAP_1_1));
$params = array('name' => 'myname', 'address' => 'myaddress');
$client->__soapCall('setContact', array('parameters' => $params), array(), null, $outputHeaders);

 

for a function like this:

 

<setContact xmlns="xmlns">
  <name>string</address>
  <address>string</address>
</setContact>

 

but how do i invoke a function for this:

 

<setContact xmlns="xmlns">
  <name title="title">string</address>
  <address>string</address>
</setContact>

 

so including the title attribute for name.

 

Thanks in advance. This is driving me crazy!

 

Share this post


Link to post
Share on other sites

$client = new SoapClient(wsdl, array('trace' => 1,  'encoding' => 'UTF-8', 'soap_version' => SOAP_1_1));

$params = array(
   'name' => array (
      "_" => "myname", 
      "title" => "title"
   ), 
   'address' => 'myaddress'
);

$client->__soapCall('setContact', array('parameters' => $params), array(), null, $outputHeaders);

 

Its been a while since i've had to do that, but i seem to recall it working like that.

Good luck

Share this post


Link to post
Share on other sites

Hi mikeschroeder,

 

thanks very much for the response. I wasn't sure if anyone was going to answer at all! Unfortunately that hasn't worked either. The error returned is still the same unhelpfulness as before:

 

Fault description: Fault occured
Fault code: soap:Server

 

I was thinking it might ave something to do with creating a soapvar first and setting the attribute through that. but i don't know how these things work.

Share this post


Link to post
Share on other sites

are you using an actual WSDL file?

For example: http://www.weather.gov/forecasts/xml/DWMLgen/wsdl/ndfdXML.wsdl

 

If you are and browse to it in your browser, you will see xml definitions representing every function you can effectively call with soap. It will also break down what a request must contain.

 

for example, I've worked with soap where i had to do something like this...

$params = array(
   'parameter' => 'value'
   'etc' => 'etc'
)

$soap->wsdlFunctionName( $params );

 

and had soap write it out to

<function>

  <parameter>value</parameter>

  <etc>etc</etc>

</function>

 

and I've also seen where functions are defined in a way:

 


$soap->wsdlFunctionName( 'value1', 'value2', 'etc' );

 

So that you had to pass the values as you would to a function in php.

 

resulting in

<function>

  <someParam>value1</someParam>

  <another>value2</another>

  <etc>etc</etc>

</function>

 

I hope that kind of makes sense, but really it could go either way. My previous solution is dependent on having to pass an array of parameters and values to a soap call. If you have to pass your values like the later example, i think the wsdl file would show you how they expect the attribute to be passed.

Share this post


Link to post
Share on other sites

I assumed that would be the case or else you would have probably included it originally.

 

Maybe this will get you pointed in the right direction.

On the weather service WSDL i provided, the function is defined as such:

<operation name="NDFDgen">
  <documentation>
    Returns National Weather Service digital weather forecast data
  </documentation>
  <input message="tns:NDFDgenRequest"/>
  <output message="tns:NDFDgenResponse"/>
</operation>

 

And the request is defined as:

 

<message name="NDFDgenRequest">
  <part name="latitude" type="xsd:decimal"/>
  <part name="longitude" type="xsd:decimal"/>
  <part name="product" type="typens:productType"/>
  <part name="startTime" type="xsd:dateTime"/>
  <part name="endTime" type="xsd:dateTime"/>
  <part name="weatherParameters" type="typens:weatherParametersType"/>
</message>

 

In this case a request would be something like this:

$soap->NDFDgen( latitude, longitude, product, starttime, endtime, weathertype );

Share this post


Link to post
Share on other sites

that certainly does work but i'm not seeing any way of dealing with attributes like

 

<function>

  <someParam id="att1">value1</someParam>

  <another>value2</another>

  <etc>etc</etc>

</function>

 

I am having some luck with using an object. I'll post back to let you know how i get on.

 

thanks again.

 

oh yeah...

 

$soap->wsdlFunctionName( 'value1', 'value2', 'etc' );

 

i don't think i can do this because it's a .net webservice??? parameters need to be passed in an array keyed parameters:

 

array('parameters' = > array ('v1' => 'value1', 'v2' => 'value2');

 

also need to login by setting the authenication header just to complicate things. but i've taken care of that. it's just this different kind of method call.

Share this post


Link to post
Share on other sites

I managed to get this to work but my understanding of what's actually happening is not that great so this is just speculation. I have been using examples and not the actual code I'm using but I'll see if i can explain.

 

the wsdl says the setContact request is formed like this:

 

<setContact xmlns="xmlns">
  <Customer id="int">
    <name>string</address>
    <address>string</address>
  </Customer>
</setContact>

 

which, I'll admit is different from my example in the first post but this is actually what i was after.

 

The soap client object is instantiated like this:

 

<?php
$client = new SoapClient(wsdl, array(
            'trace'        => 1,                                        
            'encoding'     => 'UTF-8',
            'soap_version' => SOAP_1_1,
            'classmap'     => array('Customer' => 'Customer')
        ));
?>

 

So i now create my own Customer class:

 

<?php
class Customer
{
    public $id = 0;
    public $name = "";
    public $address = "";

    function __construct($title = "", $name = "", $address = "")
    {
        $this->id = $id;
        $this->name  = $name;
        $this->address = $address;
    }
}
?>

 

So i create a Customer object:

 

<?php
$customer = new Customer(22, "name", "address");
?>

 

Now i use a SoapVar object:

 

<?php
$encodedCustomer = new SoapVar($customer, SOAP_ENC_OBJECT, "Customer", namespace);
?>

 

and call the function:

 

<?php
$client->__soapCall('setContact', array("parameters" => array("Customer" => $encodedCustomer)), array(), null, $outputHeaders);
?>

 

And somehow it works. I think the secret to this is the classmap used when instantiating the soapclient object. That and using soapvars. like i said, i'm not totally sure about the inner workings of this but i got the result i was looking for.  ;D

 

special thanks to mikeschroeder for taking an interest in this. cheers buddy!

Share this post


Link to post
Share on other sites

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.