Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 581
  • Last Modified:

XML Foreach

How would I parse and write a foreach statement for the following XML File:

<?xml version="1.0" encoding="UTF-8"?>
<notification-data-response xmlns="http://checkout.google.com/schema/2" serial-number="191d741b-b6e9-47f5-ae6a-3795494cd020">
  <notifications>
    <new-order-notification serial-number="552212673191311-00001-7">
      <buyer-billing-address>
        <address1></address1>
        <address2></address2>
        <phone></phone>
        <email>info@test.com</email>
        <contact-name>Robert </contact-name>
        <company-name></company-name>
        <fax></fax>
        <country-code>US</country-code>
        <city></city>
        <region></region>
        <postal-code>65401</postal-code>
      </buyer-billing-address>
      <timestamp>2012-08-03T21:50:02.222Z</timestamp>
      <google-order-number>552212673191311</google-order-number>
      <shopping-cart>
        <items>
          <item>
            <item-name>Cleveland Independents $25.00 Gift Card</item-name>
            <item-description></item-description>
            <unit-price currency="USD">25.0</unit-price>
            <quantity>5</quantity>
          </item>
        </items>
      </shopping-cart>
      <order-adjustment>
        <merchant-codes />
        <total-tax currency="USD">0.0</total-tax>
        <adjustment-total currency="USD">0.0</adjustment-total>
      </order-adjustment>
      <buyer-id>405269321627164</buyer-id>
      <buyer-shipping-address>
        <address1>825 Test</address1>
        <address2></address2>
        <phone></phone>
        <email>info@test.com</email>
        <contact-name>Robert</contact-name>
        <company-name></company-name>
        <fax></fax>
        <country-code>US</country-code>
        <city></city>
        <region></region>
        <postal-code></postal-code>
      </buyer-shipping-address>
      <buyer-marketing-preferences>
        <email-allowed>true</email-allowed>
      </buyer-marketing-preferences>
      <order-total currency="USD">125.0</order-total>
      <fulfillment-order-state>NEW</fulfillment-order-state>
      <financial-order-state>REVIEWING</financial-order-state>
    </new-order-notification>

Open in new window

0
rgranlund
Asked:
rgranlund
  • 5
  • 5
1 Solution
 
Ray PaseurCommented:
This does not appear to be valid XML.
0
 
Ray PaseurCommented:
Please have a look at http://www.laprbass.com/RAY_temp_rgranlund.php

I added a couple of lines to make it work.  See lines 63, 64.

<?php // RAY_temp_rgranlund.php
error_reporting(E_ALL);
echo '<pre>';


// FROM THE POST AT EE
$xml = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<notification-data-response xmlns="http://checkout.google.com/schema/2" serial-number="191d741b-b6e9-47f5-ae6a-3795494cd020">
  <notifications>
    <new-order-notification serial-number="552212673191311-00001-7">
      <buyer-billing-address>
        <address1></address1>
        <address2></address2>
        <phone></phone>
        <email>info@test.com</email>
        <contact-name>Robert </contact-name>
        <company-name></company-name>
        <fax></fax>
        <country-code>US</country-code>
        <city></city>
        <region></region>
        <postal-code>65401</postal-code>
      </buyer-billing-address>
      <timestamp>2012-08-03T21:50:02.222Z</timestamp>
      <google-order-number>552212673191311</google-order-number>
      <shopping-cart>
        <items>
          <item>
            <item-name>Cleveland Independents $25.00 Gift Card</item-name>
            <item-description></item-description>
            <unit-price currency="USD">25.0</unit-price>
            <quantity>5</quantity>
          </item>
        </items>
      </shopping-cart>
      <order-adjustment>
        <merchant-codes />
        <total-tax currency="USD">0.0</total-tax>
        <adjustment-total currency="USD">0.0</adjustment-total>
      </order-adjustment>
      <buyer-id>405269321627164</buyer-id>
      <buyer-shipping-address>
        <address1>825 Test</address1>
        <address2></address2>
        <phone></phone>
        <email>info@test.com</email>
        <contact-name>Robert</contact-name>
        <company-name></company-name>
        <fax></fax>
        <country-code>US</country-code>
        <city></city>
        <region></region>
        <postal-code></postal-code>
      </buyer-shipping-address>
      <buyer-marketing-preferences>
        <email-allowed>true</email-allowed>
      </buyer-marketing-preferences>
      <order-total currency="USD">125.0</order-total>
      <fulfillment-order-state>NEW</fulfillment-order-state>
      <financial-order-state>REVIEWING</financial-order-state>
    </new-order-notification>
    </notifications>
    </notification-data-response>
XML;

$obj = SimpleXML_Load_String($xml);
var_dump($obj);

Open in new window

0
 
rgranlundAuthor Commented:
@ray... thank you for the assistance.  What I'm really having a question/issue with is how do I parse out the return into a "foreach" statement?  I only need to know how to start it.
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
Ray PaseurCommented:
how do I parse out the return into a "foreach" statement?
PHP foreach() is an iterator.  It is used to traverse an array or object and access the elements within the larger data structure.  In order to use it effectively you need to know what elements you're interested in getting.
http://en.wikipedia.org/wiki/Iterator

Iterators are not needed in PHP if you have only one element, and it appears from the XML that we have only one of notifications, new-order-notification, shopping-cart, items, item, etc., so a foreach() example may not mean very much with this test data set.  Nevertheless, you can see the moving parts starting at line 70.  

Note the awkward notation with the squiggly braces and quotes.  This is required because the XML tags have hyphens (dashes, minus-signs) in the name.  The hyphen is usually a subtraction operator and does not make sense as part of a tag name.  You've got to wonder what Google was thinking when they set this up!  It would have made a lot more sense to me if they had used the underscore; it has no meaning in arithmetic and is commonly used as a separator_character in longer multi_word names.

<?php // RAY_temp_rgranlund.php
error_reporting(E_ALL);
echo '<pre>';


// FROM THE POST AT EE
$xml = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<notification-data-response xmlns="http://checkout.google.com/schema/2" serial-number="191d741b-b6e9-47f5-ae6a-3795494cd020">
  <notifications>
    <new-order-notification serial-number="552212673191311-00001-7">
      <buyer-billing-address>
        <address1></address1>
        <address2></address2>
        <phone></phone>
        <email>info@test.com</email>
        <contact-name>Robert </contact-name>
        <company-name></company-name>
        <fax></fax>
        <country-code>US</country-code>
        <city></city>
        <region></region>
        <postal-code>65401</postal-code>
      </buyer-billing-address>
      <timestamp>2012-08-03T21:50:02.222Z</timestamp>
      <google-order-number>552212673191311</google-order-number>
      <shopping-cart>
        <items>
          <item>
            <item-name>Cleveland Independents $25.00 Gift Card</item-name>
            <item-description></item-description>
            <unit-price currency="USD">25.0</unit-price>
            <quantity>5</quantity>
          </item>
        </items>
      </shopping-cart>
      <order-adjustment>
        <merchant-codes />
        <total-tax currency="USD">0.0</total-tax>
        <adjustment-total currency="USD">0.0</adjustment-total>
      </order-adjustment>
      <buyer-id>405269321627164</buyer-id>
      <buyer-shipping-address>
        <address1>825 Test</address1>
        <address2></address2>
        <phone></phone>
        <email>info@test.com</email>
        <contact-name>Robert</contact-name>
        <company-name></company-name>
        <fax></fax>
        <country-code>US</country-code>
        <city></city>
        <region></region>
        <postal-code></postal-code>
      </buyer-shipping-address>
      <buyer-marketing-preferences>
        <email-allowed>true</email-allowed>
      </buyer-marketing-preferences>
      <order-total currency="USD">125.0</order-total>
      <fulfillment-order-state>NEW</fulfillment-order-state>
      <financial-order-state>REVIEWING</financial-order-state>
    </new-order-notification>
  </notifications>
</notification-data-response>
XML;

// MAKE AN OBJECT
$obj = SimpleXML_Load_String($xml);

// USE ITERATORS TO ACCESS THE PROPERTIES OF THE OBJECT
foreach ($obj->notifications as $n)
{
    $s = $n->{'new-order-notification'}['serial-number'];
    echo PHP_EOL . $s;

    foreach ($n->{'new-order-notification'}->{'buyer-billing-address'} as $b)
    {
        echo PHP_EOL . $b->email;
        echo PHP_EOL . $b->{'contact-name'};
    }
}

Open in new window

HTH, ~Ray
0
 
rgranlundAuthor Commented:
@Ray.  Thank you for your continued help.  I'm finding the whole google polling API tedious but worth the learning curve.  The one issue that has come up is the following: "new Order Notifications" comes up one and the every order is specified by its own serial number.  So when I run the foreach code you have supplied, it returns one order.

So one line 76 it should be like:
foreach ($n->{'serial-number'}->{'buyer-shipping-address'} as $b)

Open in new window


 even though that wont work. Ideas?
0
 
Ray PaseurCommented:
So when I run the foreach code you have supplied, it returns one order.
Right, there is only one order in the test data, AFAIK.  Do you have some new test data that would show multiple orders?
0
 
rgranlundAuthor Commented:
@Ray

<?php
$xmlb = <<<ENDREQ
<?xml version="1.0" encoding="UTF-8"?>
<notification-data-request xmlns="http://checkout.google.com/schema/2">
  <continue-token>CKbpmu2OJxCKr4iexu0fGA0</continue-token>
</notification-data-request>
ENDREQ;

$headerb = "Authorization: Basic " . base64_encode($credentials) . "\r\n"
. "Content-type: application/xml; charset=UTF-8'" . "\r\n"
. "Accept: application/xml; charset=UTF-8" . "\r\n"
;

$fileb = curl_postb('https://202722291950428:wQqfjNYNXX2aUbZJx5Pu0A@sandbox.google.com/checkout/api/checkout/v2/reports/Merchant/202722291950428/', $xmlb, $headerb);
//var_dump($fileb);

function curl_postb($url, $post_string=NULL, $header=NULL, $timeout=4, $error_report=TRUE)
{
    // PREPARE THE CURL CALL
    $curl = curl_init();
    curl_setopt( $curl, CURLOPT_URL,            $url         );
    curl_setopt( $curl, CURLOPT_HEADER,         $header      );
    curl_setopt( $curl, CURLOPT_POST,           TRUE         );
    curl_setopt( $curl, CURLOPT_POSTFIELDS,     $post_string );
    curl_setopt( $curl, CURLOPT_TIMEOUT,        $timeout     );
    curl_setopt( $curl, CURLOPT_RETURNTRANSFER, TRUE         );

    // EXECUTE THE CURL CALL
    $htm = curl_exec($curl);
    $err = curl_errno($curl);
    $inf = curl_getinfo($curl);

    // ON FAILURE
    if (!$htm)
    {
        // PROCESS ERRORS HERE
        if ($error_report)
        {
            echo "CURL FAIL: $url TIMEOUT=$timeout, CURL_ERRNO=$err";
            echo "<pre>\n";
            var_dump($inf);
            echo "</pre>\n";
        }
        curl_close($curl);
        return FALSE;
    }

    // ON SUCCESS
    curl_close($curl);
    return $htm;
}

?>

<?php
$obj = SimpleXML_Load_String($fileb);
 
// ACTIVATE THIS TO VISUALIZE THE OBJECT
echo "<pre>\n";
var_dump($obj);
echo "</pre>\n";

// USE ITERATORS TO ACCESS THE PROPERTIES OF THE OBJECT
foreach ($obj->notifications as $n)
{
    $s = $n->{'new-order-notification'}['serial-number'];
    echo PHP_EOL . $s;

    foreach ($n->{'new-order-notification'}->{'buyer-billing-address'} as $b)
    {
        echo PHP_EOL . $b->email;
        echo PHP_EOL . $b->{'contact-name'};
    }
}
?>

Open in new window

0
 
rgranlundAuthor Commented:
The end result here is that I want to keep a bunch of the Google Order info in my own DB instead of going to Google all the time.  The second reason and the reason this has come about, is that google has no way of sending out a customized email once the order is finished.
0
 
Ray PaseurCommented:
See: http://www.laprbass.com/RAY_temp_rgranlund.php

<?php // RAY_temp_rgranlund.php
error_reporting(E_ALL);
echo "<pre>\n";

$xmlb = <<<ENDREQ
<?xml version="1.0" encoding="UTF-8"?>
<notification-data-request xmlns="http://checkout.google.com/schema/2">
  <continue-token>CKbpmu2OJxCKr4iexu0fGA0</continue-token>
</notification-data-request>
ENDREQ;

$headerb = "Authorization: Basic " . "\r\n"
. "Content-type: application/xml; charset=UTF-8'" . "\r\n"
. "Accept: application/xml; charset=UTF-8" . "\r\n"
;

$fileb = curl_postb('https://202722291950428:wQqfjNYNXX2aUbZJx5Pu0A@sandbox.google.com/checkout/api/checkout/v2/reports/Merchant/202722291950428/', $xmlb, $headerb);
//var_dump($fileb);

function curl_postb($url, $post_string=NULL, $header=NULL, $timeout=4, $error_report=TRUE)
{
    // PREPARE THE CURL CALL
    $curl = curl_init();
    curl_setopt( $curl, CURLOPT_URL,            $url         );
    curl_setopt( $curl, CURLOPT_HEADER,         $header      );
    curl_setopt( $curl, CURLOPT_POST,           TRUE         );
    curl_setopt( $curl, CURLOPT_POSTFIELDS,     $post_string );
    curl_setopt( $curl, CURLOPT_TIMEOUT,        $timeout     );
    curl_setopt( $curl, CURLOPT_RETURNTRANSFER, TRUE         );

    // EXECUTE THE CURL CALL
    $htm = curl_exec($curl);
    $err = curl_errno($curl);
    $inf = curl_getinfo($curl);

    // ON FAILURE
    if (!$htm)
    {
        // PROCESS ERRORS HERE
        if ($error_report)
        {
            echo "CURL FAIL: $url TIMEOUT=$timeout, CURL_ERRNO=$err";
            echo "<pre>\n";
            var_dump($inf);
            echo "</pre>\n";
        }
        curl_close($curl);
        return FALSE;
    }

    // ON SUCCESS
    curl_close($curl);
    return $htm;
}

?>

<?php
$obj = SimpleXML_Load_String($fileb);

// ACTIVATE THIS TO VISUALIZE THE OBJECT
// print_r($obj);

// USE ITERATORS TO ACCESS THE PROPERTIES OF THE OBJECT
foreach ($obj->notifications as $n)
{
    $s = $n->{'new-order-notification'}['serial-number'];
    echo PHP_EOL . $s;
    echo PHP_EOL;

    foreach ($n->{'new-order-notification'} as $o)
    {
        echo PHP_EOL . ($o->{'buyer-billing-address'}->{'contact-name'});
        foreach ($o->{'shopping-cart'}->items->item as $i)
        {
            echo PHP_EOL . $i->{'item-name'};
            echo $i->{'item-price'};
        }
        echo PHP_EOL;
    }
}

Open in new window

0
 
rgranlundAuthor Commented:
OK, this is awesome.  I will continue forward and find out how I can break it!... again...
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

  • 5
  • 5
Tackle projects and never again get stuck behind a technical roadblock.
Join Now