Hello,

I'm new to PHP but have been coding in Perl for over six years. I've had a steep learning curve in the last few days. My task has been to use fsockopen to pull in an XML stream, parse that XML stream, and package up that data into a complex, but usable data structure. We've been able to accomplish this in Perl but now I'm attempting to port the Perl code to PHP. The Perl code was written by Randal Schwartz (for me) but he's not interested in helping me solve the PHP problems I'm running into. I'm hoping to find someone on this list savvy in Perl and PHP, and understands complex data structures (in perl the hash refs/pointers go about four levels deep). I've included below the PHP code with three functions in question. Below each function is the Perl code I'm attempting to port.

Here are some URL's that might help:

http://shop.sprocketdata.com/test.php - url for the code below (which works if you copy paste)
ignore the feof error- i left out the fsockopen because I know that's not where the problem is nor does this error effect the output.


http://stage.holdit.com/cgi-bin/is/shipping.cgi - url for equivalent code in perl (ignore the drop-down)

http://stage.holdit.com/cgi-bin/is/fetch.cgi - the data structure I'm trying to achieve in PHP

http://stage.holdit.com/cgi-bin/is/is.cgi - the raw XML data structure - almost useless until parsed and probably useless to look at :-).

You'll also notice at the bottom of the code I've included how the PHP XML parsed the data. It's very similar to the fetch.cgi - maybe it's different and thus causing the problem but I don't see it.

<?php

$state = array();
global $state;

// these two associatative arrays will hold the data structure (I hope :-)
$quote = array();
global $quote;
$quotes = array();
global $quotes;


//XML start element
function startElement(&$Parser, &$Elem, &$Attr) {
global $state; //this works
array_push ($state, $Elem); //this works
$states = join (' ',$state); //can't interpolate the list so must join - works
if ($states = "SHIPMENT PACKAGE") { //we make it this far
echo "$states\n"; //for testing should on print once!
// $package_id = $Attr->{id}; // how to write this in PHP?
}
//This conditional is never met - QUOTE gets popped off before it returns
elseif ($states = "SHIPMENT PACKAGE QUOTE") { //why does perl see QUOTE?
echo "$states\n"; // testing
// %quote = ( package_id => $package_id, id => $attr->{id} ); //Perl
// $quote = array ( package_id => $package_id, id => $attr->{id} ); //PHP version of above line?
}
}


/*Perl
start_h => [ sub {
        my ($tagname, $attr) = @_;
        push @state, $tagname;
        if ("@state" eq "shipment package") {
                print "@state<br>";#testing
                $package_id = $attr->{id};
        }
        elsif ("@state" eq "shipment package quote") {
                %quote = ( package_id => $package_id, id => $attr->{id} );
                print "@state<br>";#testing
        }
}, "tagname, attr"],
*/

// XML data
//This function might work but I don't know yet as QUOTE never stays in the $state stack
function characterData(&$Parser, &$Line) {
global $state;
$states = join (' ',$state);
if ($states = "SHIPPMENT ERROR") {
$error = $Line;
}
elseif ($states = "SHIPMENT PACKAGE QUOTE BOXID") {
$boxID = $Line;
}
elseif ($states = "SHIPMENT PACKAGE QUOTE CARRIER NAME") {
$quote{carrier_name} = $Line; // Doubting this will work - need to fix this too
}
elseif ($states = "SHIPMENT PACKAGE QUOTE CARRIER CODE") {
$quote{carrier_code} = $Line;
}
elseif ($states = "SHIPMENT PACKAGE QUOTE CLASS NAME") {
$quote{class_name} = $Line;
}
elseif ($states = "SHIPMENT PACKAGE QUOTE CLASS CODE") {
$quote{class_code} = $Line;
}
elseif ($states = "SHIPMENT PACKAGE QUOTE SERVICE NAME") {
$quote{service_name} = $Line;
}
elseif ($states = "SHIPMENT PACKAGE QUOTE SERVICE CODE") {
$quote{service_code} = $Line;
}
elseif ($states = "SHIPMENT PACKAGE QUOTE RATE AMOUNT") {
$quote{amount} = $Line;
}
}


/* Perl
text_h => [ sub {
        my ($text) = @_;
        if ("@state" eq "shipment error") {
                $error = $text;
        }
        elsif ("@state" eq "shipment package boxID") {
                $boxID = $text;
        }
        elsif ("@state" eq "shipment package quote carrier name") {
                $quote{carrier_name} = $text;
        }
        elsif ("@state" eq "shipment package quote carrier code") {
                $quote{carrier_code} = $text;
        }
        elsif ("@state" eq "shipment package quote class name") {
                $quote{class_name} = $text;
        }
        elsif ("@state" eq "shipment package quote class code") {
                $quote{class_code} = $text;
        }
        elsif ("@state" eq "shipment package quote service name") {
                $quote{service_name} = $text;
        }
        elsif ("@state" eq "shipment package quote service code") {
                $quote{service_code} = $text;
        }
        elsif ("@state" eq "shipment package quote rate amount") {
                $quote{amount} = $text;
        }
}, "dtext"],
*/


function endElement(&$Parser, &$Elem) { global $state; $states = join (' ',$state); if ($states = "SHIPMENT PACKAGE QUOTE") { //echo "got QUOTE here $states\n"; /* The following three lines need porting to PHP there is much perl magic here - I can explain if it doesn't make sense. The short of this is it's a rather complex structure Perhaps this is where things are breaking? */ //$key = "@quote{qw(carrier_code service_code)}"; //delete @quote{qw(id package_id)}; # artificial //$quotes{$boxID}{$key} = {%quote}; } // obviously the part that pulls QUOTE off the $state stack // perhaps a conditional? array_pop($state); }

/*Perl
end_h => [ sub {
        my ($tagname) = @_;
        if ("@state" eq "shipment package quote") {
                my $key = "@quote{qw(carrier_code service_code)}";
                delete @quote{qw(id package_id)}; # artificial
                $quotes{$boxID}{$key} = {%quote};
        }
        pop @state;
}, "tagname"],
*/



//This code should work just fine
echo '<html><body><pre><form>';
$xml_parser = xml_parser_create();
xml_set_element_handler($xml_parser, "startElement", "endElement");
xml_set_character_data_handler($xml_parser, "characterData");

//The XML data as returned from the server in it's raw form
$data = '<?xml version="1.0"?><shipment xsi:schemaLocation="http://www.intershipper.com/Interface/Intershipper/ XML/v2.0/schemas response.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema- instance"><version>2.0.0.0</version><shipmentID>1234</ shipmentID><queryID>23456</queryID><deliveryType>COM</ deliveryType><shipMethod>DRP</shipMethod><origination><name>John Smith</name><address1>465 Tyende Ovi</address1><address2></address2><address3></ address3><city>Flagstaff</city><state>AZ</state><postal>86001</ postal><country>US</country></origination><destination><name>Jane Doe</name><address1>466 Tyende Ovi</address1><address2></address2><address3></ address3><city>Flagstaff</city><state>AZ</state><postal>86001</ postal><country>US</country></destination><package id="1"><boxID>1</boxID><weight unit="LB">10.0</weight><dimensions unit="IN"><length>10.0</length><width>10.0</width><height>10.0</ height></dimensions><packaging>BOX</packaging><contents>OTR</ contents><cod>18500</cod><insurance>15000</ insurance><options><specialHandling id="1"><code>SDD</code><name>Saturday Delivery</name></specialHandling></options><quote id="1"><carrier><code>UPS</code><name>United Parcel Service</name><account>123456789</account><invoiced>1</invoiced></ carrier><class><code>1DY</code><name>1st Day</name></class><service><code>NDA</code><name>Next Day Air</name></service><rate><amount>4201</amount><currency>USD</ currency></rate></quote><quote id="2"><carrier><code>UPS</code><name>United Parcel Service</name><account>123456789</account><invoiced>1</invoiced></ carrier><class><code>1DY</code><name>1st Day</name></class><service><code>NDS</code><name>Next Day Air Saver</name></service><rate><amount>3898</amount><currency>USD</ currency></rate></quote><quote id="3"><carrier><code>UPS</code><name>United Parcel Service</name><account>123456789</account><invoiced>1</invoiced></ carrier><class><code>1DY</code><name>1st Day</name></class><service><code>NDM</code><name>Next Day Air AM</name></service><rate><amount>7087</amount><currency>USD</ currency></rate></quote></package></shipment>';


if (!xml_parse($xml_parser, $data, feof($fp))) {
        die(sprintf("XML error: %s at line %d",
        xml_error_string(xml_get_error_code($xml_parser)),
        xml_get_current_line_number($xml_parser)));
}
xml_parser_free($xml_parser);
echo '</select></form>';


/* Here is an example of the data returned from the XML parser

SHIPMENT:
  VERSION: 2.0.0.0
  SHIPMENTID: 1234
  QUERYID: 23456
  DELIVERYTYPE: COM
  SHIPMETHOD: DRP
  ORIGINATION:
    NAME: John Smith
    ADDRESS1: 465 Tyende Ovi
    ADDRESS2:
    ADDRESS3:
    CITY: Flagstaff
    STATE: AZ
    POSTAL: 86001
    COUNTRY: US
  DESTINATION:
    NAME: Jane Doe
    ADDRESS1: 466 Tyende Ovi
    ADDRESS2:
    ADDRESS3:
    CITY: Flagstaff
    STATE: AZ
    POSTAL: 86001
    COUNTRY: US
  PACKAGE:
    BOXID: 1
    WEIGHT: 10.0
    DIMENSIONS:
      LENGTH: 10.0
      WIDTH: 10.0
      HEIGHT: 10.0
    PACKAGING: BOX
    CONTENTS: OTR
    COD: 18500
    INSURANCE: 15000
    OPTIONS:
      SPECIALHANDLING:
      CODE: SDD
        NAME: Saturday Delivery
    QUOTE:
      CARRIER:
        CODE: UPS
        NAME: United Parcel Service
        ACCOUNT: 123456789
        INVOICED: 1
      CLASS:
        CODE: 1DY
        NAME: 1st Day
      SERVICE:
        CODE: NDA
        NAME: Next Day Air
      RATE:
        AMOUNT: 4201
        CURRENCY: USD
    QUOTE:
      CARRIER:
        CODE: UPS
        NAME: United Parcel Service
        ACCOUNT: 123456789
        INVOICED: 1
      CLASS:
        CODE: 1DY
        NAME: 1st Day
      SERVICE:
        CODE: NDS
        NAME: Next Day Air Saver
      RATE:
        AMOUNT: 3898
        CURRENCY: USD
    QUOTE:
      CARRIER:
        CODE: UPS
        NAME: United Parcel Service
        ACCOUNT: 123456789
        INVOICED: 1
      CLASS:
        CODE: 1DY
        NAME: 1st Day
      SERVICE:
        CODE: NDM
        NAME: Next Day Air AM
      RATE:
        AMOUNT: 7087
        CURRENCY: USD
*/
?>


I do apologize for the length of this email. I did my best to make it short.



-- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php



Reply via email to