0

I am doing my first steps with WordPress_plugins/PHP and just faced my first wall. Will try to do my best in order to explain the problem, please give me some discount.

I am creating a plugin for WordPress website that needs to call an external Rest API server and get the inventory value of a specific product, for this purpose I am using wp_remote_get & wp_remote_retrieve_body. Until this point everything is working fine, the connection is made successfully and I do get the response in XML.

The problem starts when I try to extract the data (value of the quantity in stock) from the XML response. For some reason it is resulting in NULL, I have printed the response just to make sure the data is actually there and indeed it is.

Also, I stored the printed response in to a variable and tried to use the same logic in order to get the value I am looking for and it worked just fine.

Please see my code/comments below, any advice will be much appreciated, thank you:

//The Rest API xml response obtained by wp_remote_get & wp_remote_retrieve_body.
$response_body          = get_api_response($api_url, $arguments);
//The xml data for the "$response_body_manual" was obtained by "Copy Outer HTML" when inspecting the printed/echo element of the "$response_body" on the web browser
$response_body_manual = 
   '<!--?xml version="1.0" encoding="UTF-8"?-->
    <inventories>
        <inventory>
            <product>TestProduct</product>
            <productinventories>
                <productinventory>
                    <site>101</site>
                    <quantityinstock>238.00000</quantityinstock>
                    <quantityhardallocated>0.00000</quantityhardallocated>
                    <quantitysoftallocated>0.00000</quantitysoftallocated>
                </productinventory>
            </productinventories>
        </inventory>
    </inventories>';

//Parse the response
$xml        = simplexml_load_string($response_body);
$xml_manual = simplexml_load_string($response_body_manual);

//Get the quantityinstock value
$QtyInStock_xml         = $xml->inventory->productinventories->productinventory->quantityinstock;
$QtyInStock_xml_manual  = $xml_manual->inventory->productinventories->productinventory->quantityinstock;

//Print out the results
echo "<center><pre>";
print($response_body  . "<br>");
print("XML String loaded successfully"  . "<br>");
print("Quantity_in_stock_xml -> " . $QtyInStock_xml . "<br>");
print("Quantity_in_stock_xml_manual -> " . $QtyInStock_xml_manual . "<br>");
echo "</center></pre>";

//Result
//
//<pre>
//  <!--?xml version="1.0" encoding="UTF-8"?-->
//  <inventories>
//      <inventory>
//          <product>TestProduct</product>
//          <productinventories>
//              <productinventory>
//                  <site>101</site>
//                  <quantityinstock>238.00000</quantityinstock>
//                  <quantityhardallocated>0.00000</quantityhardallocated>
//                  <quantitysoftallocated>0.00000</quantitysoftallocated>
//              </productinventory>
//          </productinventories>
//      </inventory>
//  </inventories>
//
//<br>XML String loaded successfully
//<br>Quantity_in_stock_xml -&gt; 
//<br>Quantity_in_stock_xml_manual -&gt; 238.00000<br></pre>

As you can see, I am able to get the quantity in stock value when using a manually created response but not when directly from the api response variable.

Question: What am I missing/doing wrong when getting the XML element value directly from the API response variable?

Thank you

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

18-03-2020 15:30

Based on Mikhail's suggestion I did some XML error testing, please see below:

I run my script with the below code added to it and the result was "No loading errors found.":

    libxml_use_internal_errors(true);
    $sxe = simplexml_load_string($response_body);
    if ($sxe === false) {
        echo "Failed loading XML\n";
        foreach(libxml_get_errors() as $error) {
            echo "<center><pre>";
            echo "\t", $error->message;
            echo "</center></pre>";
        }
    }
    else{
        echo "<center><pre>";
        echo "No loading errors found.<br>";
        print_r($sxe);
        echo "</center></pre>";
    }

Also, the print result of simplexml_load_string($response_body) is like this:

SimpleXMLElement Object
(
    [Inventory] => SimpleXMLElement Object
        (
            [Product] => TestProduct
            [ProductInventories] => SimpleXMLElement Object
                (
                    [ProductInventory] => SimpleXMLElement Object
                        (
                            [Site] => 101
                            [QuantityInStock] => 238.00000
                            [QuantityHardAllocated] => 0.00000
                            [QuantitySoftAllocated] => 0.00000
                        )

                )

        )

)

I don't really understand what is wrong... Thank you guys in advance for any help.

  • We don't know what your get_api_response function returns in fact, check what it returns exactly. – Mikhail Mar 17 at 16:25
  • Hi Mikhail, thanks for your reply. When I print() or var_dump() the $response_body variable, I get exactly the XML data that was provided in the first half of the "//Result" section of the initial post. If this is not good, please would you be able to advise of any other test I could do in order to provide with a more adequate result? Thank you – Petru Mar 17 at 17:05
  • Just to add: I printed the return of the get_api_response function as shown on the initial post and it printed a proper XML response, exactly the same thing that I get when I do some testing directly on the API website/server. The variable $response_body_manual is provided with an exact copy of what the print of the response displayed. (Not 100% sure if this makes sense, but I don't know how better to explain it). Thank you – Petru Mar 17 at 17:12
  • I got your point. What you can do is follow PHP's guide on debugging xml parsing php.net/manual/en/simplexml.examples-errors.php So at least you'll know what exactly going on with this xml which looks exactly the same. – Mikhail Mar 17 at 19:49
  • Thank you, Mikhail, will give it a go and come back later on with news if any. – Petru Mar 18 at 9:46
0

And according to your output

SimpleXMLElement Object
(
    [Inventory] => SimpleXMLElement Object
        (
            [Product] => TestProduct
            [ProductInventories] => SimpleXMLElement Object
                (
                    [ProductInventory] => SimpleXMLElement Object
                        (
                            [Site] => 101
                            [QuantityInStock] => 238.00000
                            [QuantityHardAllocated] => 0.00000
                            [QuantitySoftAllocated] => 0.00000
                        )

                )

        )

)

You have to access your variable inside object parsed from this XML as:

$QtyInStock_xml  = $xml_parsed_obj->Inventory->ProductInventories->ProductInventory->QuantityInStock;

Just because XML is case sensitive ! and object's keys in PHP are case sensitive too.

Overall keep in mind that PHP's variables are case sensitive.

If to dig deeper function names are non case sensitive, but never rely on it! forget about it and never disrespect function's name case !

Just accept it as a rule that whatever code you type, either it's a variable or function - treat everything as case sensitive and may the good code be with you :)

| improve this answer | |
  • Oh no, can't believe it... I guess this is what happens when a python oriented mind starts messing with PHP. I did a quick test and it JUST WORKS ... Thank you, Mikhail, will give more attention to this kind of things from now on. – Petru Mar 19 at 9:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.