Get element from WSDL in PHP using SoapClient
Asked Answered
J

2

12

I'd like to get the text from the <Version> element which is nested inside the <service> block of a WSDL. The WSDL in question is Ebay's Trading api. The snippet in question looks something like this:

<wsdl:service name="eBayAPIInterfaceService">
    <wsdl:documentation>
        <Version>941</Version>
    </wsdl:documentation>
    <wsdl:port binding="ns:eBayAPISoapBinding" name="eBayAPI">
        <wsdlsoap:address location="https://api.ebay.com/wsapi"/>
    </wsdl:port>
</wsdl:service>

I'm currently doing this:

$xml = new DOMDocument();
$xml->load($this->wsdl);
$version = $xml->getElementsByTagName('Version')->item(0)->nodeValue;

This works but I'm wondering if there is a method to get this natively using PHP's SOAP extension?

I was thinking something like the following would work but it doesn't:

$client = new SoapClient($this->wsdl);
$version = $client->eBayAPIInterfaceService->Version;
Jarib answered 13/10, 2015 at 18:35 Comment(8)
I think posting just a link as an answer is bad form, so I'm commenting instead. I found this link really useful in learning how to use the SoapClient PHP class devzone.zend.com/2202/php-and-soap-first-steps It gives examples in using a WSDL. That class returns the data as an object that you can grab the data from.Dev
@Dev - I don't see any way to get that element from the SoapClient class. I can initialize the client, call methods, get properties, etc but for the life of me I can't figure out how to access <service>. The wsdl is publicly available here developer.ebay.com/webservices/latest/ebaysvc.wsdl. If you can provide a working example using SoapClient that would be very helpful.Jarib
I started to look at it for you, but the ebay API seems infinitely more complex than the API I've been working with. I found this SO answer though - it seems to have a working example: #16502707 Good luck.Dev
@Dev - I don't think you understand what I'm asking here. I'm not having any problem connecting or calling methods.Jarib
If you don't succeed with the SoapClient, probably you may want to have a look at xpath, which is a much clearer way to access XML-Elements than a bunch of method calls on PHP objects.Snare
How is xpath is any more clear than the single line of code using DOM Document which I'm already using? $xml->getElementsByTagName('Version')->item(0)->nodeValue;Jarib
I think you may need something like this $version = $client->service->documentation->version; but I advise you to go in debugging mode and see the exactly structure there.Placentation
@Placentation - no that doesn't work.Jarib
P
4

It is not possible to do what you want with the regular SoapClient. Your best bet is to extend the SoapClient class and abstract-away this requirement to get the version.

Please beware that file_get_contents is not cached so it will always load the WSDL file. On the other hand SoapClient caches the WSDL so you will have to deal with it yourself.

Perhaps look into NuSOAP. You will be able to modify the code to suit your purposes without loading the WSDL twice (of course you are able to modify SoapClient too but that's another championship ;) )

namespace Application;

use DOMDocument;

class SoapClient extends \SoapClient {
    private $version = null;

    function __construct($wsdl, $options = array()) {
        $data = file_get_contents($wsdl);

        $xml = new DOMDocument();
        $xml->loadXML($data);
        $this->version = $xml->getElementsByTagName('Version')->item(0)->nodeValue;

        // or just use $wsdl :P
        // this is just to reuse the already loaded WSDL
        $data = "data://text/plain;base64,".base64_encode($data);
        parent::__construct($data, $options);
    }

    public function getVersion() {
        return is_null($this->version) ? "Uknown" : $this->version;
    }
}

$client = new SoapClient("http://developer.ebay.com/webservices/latest/ebaysvc.wsdl");
var_dump($client->getVersion());
Pheni answered 26/10, 2015 at 18:45 Comment(1)
This is far from ideal and about 1000x more cumbersome than what I'm already doing. But thanks all the same for contributing an idea.Jarib
A
0

Have you tried simplexml_load_file? Worked for me when i needed to parse an XML-File with php.

<?php

$file = "/path/to/yourfile.wsdl";

$xml = simplexml_load_file($file) or die ("Error while loading: ".$file."\n");

echo $xml->service->documentation->Version;

//if there are more Service-Elements access them via index
echo $xml->service[index]->documentation->Version;

//...where index in the number of the service appearing
//if you count them from top to buttom. So if "eBayAPIInterfaceService"
//is the third service-Element
echo $xml->service[2]->documentation->Version;



?>
Anglicanism answered 27/10, 2015 at 18:38 Comment(1)
The question is specifically relating to PHP SOAP Client so this answer is not relevant and also redundant as I've already demonstrated something similar which works fine using DOM Document. I revised the title to make this more clear.Jarib

© 2022 - 2024 — McMap. All rights reserved.