0

What am I trying to reach: I am trying to get a reponse from a webserver. With this response i have some data that I need to extract. I already have reached the point to receive a response from the webservice.

What is the problem: I have the data response from the server using cURL, but I can not extract data out of the answer because that always returns a empty value.

What I tried: I tried to parse the result in a array ( no value returned ) I tried to parse the result with new SimpleXMLElement ( empty object ) I tried to encode it with JSON en decode it again ( empty array) I tried to explode the result ( returns no good values )

I don't know what to do anymore, could someone take a look.

My cURL code:

$xml = '
    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://dpd.com/common/service/types/Authentication/2.0" xmlns:ns1="http://dpd.com/common/service/types/ShipmentService/3.1"> 
    <soapenv:Header> 
        <ns:authentication> 
            <delisId>'.$delisId.'</delisId> 
            <authToken>'.$auth_token.'</authToken> 
            <messageLanguage>'.$messageLanguage.'</messageLanguage> 
        </ns:authentication> 
    </soapenv:Header> 
    <soapenv:Body> 
        <ns1:storeOrders> 
            <printOptions> 
                <printerLanguage>'.$printerLanguage.'</printerLanguage> 
                <paperFormat>'.$paperFormat.'</paperFormat> 
            </printOptions> 
            <order> 
                <generalShipmentData> 
                    <identificationNumber>'.$identificationNumber.'</identificationNumber> 
                    <sendingDepot>'.$sendingDepot.'</sendingDepot> 
                    <product>'.$product.'</product> 
                    <mpsCompleteDelivery>'.$mpsCompleteDelivery.'</mpsCompleteDelivery> 
                    <sender> 
                        <name1>'.$send_name.'</name1> 
                        <street>'.$send_street.'</street> 
                        <country>'.$send_country.'</country> 
                        <zipCode>'.$send_zipcode.'</zipCode> 
                        <city>'.$send_city.'</city> 
                        <customerNumber>'.$send_customerNumber.'</customerNumber> 
                    </sender> 
                    <recipient> 
                        <name1>'.$rec_name.'</name1> 
                        <street>'.$rec_street.'</street> 
                        <state>'.$rec_state.'</state> 
                        <country>'.$rec_country.'</country> 
                        <zipCode>'.$rec_zipcode.'</zipCode> 
                        <city>'.$rec_city.'</city> 
                    </recipient> 
                </generalShipmentData> 
                <parcels> 
                    <parcelLabelNumber>'.$parcelLabelNumber.'</parcelLabelNumber> 
                </parcels> 
                <productAndServiceData> 
                    <orderType>'.$orderType.'</orderType> 
                </productAndServiceData> 
            </order> 
        </ns1:storeOrders> 
    </soapenv:Body> 
</soapenv:Envelope>
    ';

    $headers = array(
        "POST  HTTP/1.1",
        "Content-type: application/soap+xml; charset=\"utf-8\"",
        "SOAPAction: \"http://dpd.com/common/service/ShipmentService/3.1/storeOrders\"",
        "Content-length: ".strlen($xml)
    );

    $url = 'https://public-ws-stage.dpd.com/services/ShipmentService/V3_1/';

    $cl = curl_init();
    curl_setopt($cl, CURLOPT_URL, $url);
    curl_setopt($cl, CURLOPT_SSL_VERIFYHOST, 0);
    curl_setopt($cl, CURLOPT_SSL_VERIFYPEER, 0);
    curl_setopt($cl, CURLOPT_POST, 1);
    curl_setopt($cl, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($cl, CURLOPT_POSTFIELDS, "$xml");
    curl_setopt($cl, CURLOPT_RETURNTRANSFER, 1);
    $output_cl = curl_exec($cl);
    curl_close($cl);

    //return $output_cl;


    $output_xml = new SimpleXMLElement($output_cl);

    foreach($output_xml->orderresult as $orderresult)
    {
        foreach($orderresult->parcellabelspdf as $pdf)
        {
            return $pdf;
        }
    }

Response from the server ( i think in a string format, but don't know for sure):

<soap:envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:body>
        <ns2:storeordersresponse xmlns:ns2="http://dpd.com/common/service/types/ShipmentService/3.1">
            <orderresult>
                <parcellabelspdf>pdflabel</parcellabelspdf>
                <shipmentresponses>
                    <identificationnumber>idnumber</identificationnumber>
                    <mpsid>mpsid</mpsid>
                    <parcelinformation>
                        <parcellabelnumber>labelnumber</parcellabelnumber>
                    </parcelinformation>
                </shipmentresponses>
            </orderresult>
        </ns2:storeordersresponse>
    </soap:body>
</soap:envelope>

I would like to extract the parcellabelspdf value and the mpsid value.

user3734231
  • 40
  • 1
  • 15

2 Answers2

1

Try using the DOMDocument

$doc = new DOMDocument();
$doc->loadXML($output_cl);

$mpsid = $doc->getElementsByTagName( "mpsid" );
$mpsid_value= $mpsid->item(0)->nodeValue;
Athafoud
  • 2,898
  • 3
  • 40
  • 58
  • I did just try your solution but I still have no value that returns. – user3734231 Jun 23 '14 at 10:46
  • So i think that you may have an error when you parsing the envelope. Check your syntax and try `var_dump($doc)` to see if the string is loaded correclty. – Athafoud Jun 23 '14 at 10:55
  • If i use var_dump($doc) after the lines you wrote i get the following response: object(DOMDocument)#2 (0) { }. And i checked all my syntaxes for mistakes, but I couldn't find one. Maybe you could find one. Is the reponse from the var dump good or not? – user3734231 Jun 23 '14 at 10:58
  • The result of the `var_dump()` is not good. Also as i see it you response envelope is formated correclty. The only thing i can think is that you have parsing errors. Did you set your php configuration to display all errors and warnings? – Athafoud Jun 23 '14 at 11:29
  • Yes it shows everything, and I even tried now to put the response just in a string witouth calling it from the webservice and then parsing it to an object. But that also returns an empty object. Could you maybe post an example of how you would convert just the string to an object, and reference to its nodes? – user3734231 Jun 23 '14 at 11:31
  • The way i am doing it is with `DOMDocument` as in my anwser. Try after `loadXMl()` to use [public string DOMDocument::saveXML](http://www.php.net/manual/en/domdocument.savexml.php) and `echo` the anwser to see if the string was parsed correctly (which i doupt) – Athafoud Jun 23 '14 at 11:41
  • I just tried the above code (from my anwser) giving the `$output_cl` as a string, everything works perfect – Athafoud Jun 23 '14 at 11:47
  • I tried your document in a new php file with just a string, it worked indeed. But then i changed the source so not the real string but the output from the cURL and it gives no value. Is it maybe that the cURL gives a different type of reponse that can not communicate with your code or something? – user3734231 Jun 23 '14 at 12:08
  • Your code expect it to be an direct XML input. But the answer of the webserver is a string including XML tags, so it has to become a XML string first. Any idea how i could do that ? – user3734231 Jun 23 '14 at 12:16
0

Here is a commented code-example. You have basically problems to understand how to access the namespaces. My example shows this verbose (which I also suggest when you build that yourself, use ->asXML() in between to debug how far you've come).

<?php
/*
 * @link https://stackoverflow.com/questions/24363786/extract-data-from-curl-response-keeps-returning-no-value
 */

$buffer = <<<XML
<soap:envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:body>
        <ns2:storeordersresponse xmlns:ns2="http://dpd.com/common/service/types/ShipmentService/3.1">
            <orderresult>
                <parcellabelspdf>pdflabel</parcellabelspdf>
                <shipmentresponses>
                    <identificationnumber>idnumber</identificationnumber>
                    <mpsid>mpsid</mpsid>
                    <parcelinformation>
                        <parcellabelnumber>labelnumber</parcellabelnumber>
                    </parcelinformation>
                </shipmentresponses>
            </orderresult>
        </ns2:storeordersresponse>
    </soap:body>
</soap:envelope>
XML;


$xml = simplexml_load_string($buffer);

// into <soap:*> namespace
$body        = $xml->children('soap', true)->body;

// into <ns2:*> namespace
$storeordersresponse = $body->children('ns2', true)->storeordersresponse;

// into document default namespace (no namespace)
$orderresult = $storeordersresponse->children()->orderresult; 

// you can now traverse as usual as you've reached the <orderresult> element
$mpsid       = $orderresult->shipmentresponses->mpsid;

echo $mpsid->asXML(); // prints "<mpsid>mpsid</mpsid>"

If you don't want to do the traversal all in your code and you've somewhat understood how that is going to work with the namespaces, there is this old but very useful Q&A. It introdcues to XPath which can spare you a lot of typing:

Community
  • 1
  • 1
hakre
  • 193,403
  • 52
  • 435
  • 836