if( $states == "SHIPMENT PACKAGE" ) {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
^^
elseif( $states == "SHIPMENT PACKAGE QUOTE" ){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?
^^
if( $states == "SHIPMENT ERROR" ) {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") {
^^
elseif( $states == "SHIPMENT PACKAGE QUOTE BOXID" ) {$error = $Line; } elseif ($states = "SHIPMENT PACKAGE QUOTE BOXID") {
^^
elseif( $states == "SHIPMENT PACKAGE QUOTE CARRIER NAME" ) {$boxID = $Line; } elseif ($states = "SHIPMENT PACKAGE QUOTE CARRIER NAME") {
^^
elseif( $states == "SHIPMENT PACKAGE QUOTE CARRIER CODE" ) {$quote{carrier_name} = $Line; // Doubting this will work - need to fix this too } elseif ($states = "SHIPMENT PACKAGE QUOTE CARRIER CODE") {
^^
elseif( $states == "SHIPMENT PACKAGE QUOTE CLASS NAME" ) {$quote{carrier_code} = $Line; } elseif ($states = "SHIPMENT PACKAGE QUOTE CLASS NAME") {
^^
elseif( $states == "SHIPMENT PACKAGE QUOTE CLASS CODE" ) {$quote{class_name} = $Line; } elseif ($states = "SHIPMENT PACKAGE QUOTE CLASS CODE") {
^^
elseif( $states == "SHIPMENT PACKAGE QUOTE SERVICE NAME" ) {$quote{class_code} = $Line; } elseif ($states = "SHIPMENT PACKAGE QUOTE SERVICE NAME") {
^^
elseif( $states == "SHIPMENT PACKAGE QUOTE SERVICE CODE" ) {$quote{service_name} = $Line; } elseif ($states = "SHIPMENT PACKAGE QUOTE SERVICE CODE") {
^^
elseif( $states == "SHIPMENT PACKAGE QUOTE RATE AMOUNT" ) {$quote{service_code} = $Line; } elseif ($states = "SHIPMENT PACKAGE QUOTE RATE AMOUNT") {
^^
if( $states == "SHIPMENT PACKAGE QUOTE" ) {$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 = ''; 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.
-- Tyler Lane <[EMAIL PROTECTED]> |
signature.asc
Description: This is a digitally signed message part