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
^^
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?
elseif( $states == "SHIPMENT PACKAGE 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") {
if( $states == "SHIPMENT ERROR" ) {^^
$error = $Line;
}
elseif ($states = "SHIPMENT PACKAGE QUOTE BOXID") {
elseif( $states == "SHIPMENT PACKAGE QUOTE BOXID" ) {^^
$boxID = $Line;
}
elseif ($states = "SHIPMENT PACKAGE QUOTE CARRIER NAME") {
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") {
elseif( $states == "SHIPMENT PACKAGE QUOTE CARRIER CODE" ) {^^
$quote{carrier_code} = $Line;
}
elseif ($states = "SHIPMENT PACKAGE QUOTE CLASS NAME") {
elseif( $states == "SHIPMENT PACKAGE QUOTE CLASS NAME" ) {^^
$quote{class_name} = $Line;
}
elseif ($states = "SHIPMENT PACKAGE QUOTE CLASS CODE") {
elseif( $states == "SHIPMENT PACKAGE QUOTE CLASS CODE" ) {^^
$quote{class_code} = $Line;
}
elseif ($states = "SHIPMENT PACKAGE QUOTE SERVICE NAME") {
elseif( $states == "SHIPMENT PACKAGE QUOTE SERVICE NAME" ) {^^
$quote{service_name} = $Line;
}
elseif ($states = "SHIPMENT PACKAGE QUOTE SERVICE CODE") {
elseif( $states == "SHIPMENT PACKAGE QUOTE SERVICE CODE" ) {^^
$quote{service_code} = $Line;
}
elseif ($states = "SHIPMENT PACKAGE QUOTE RATE AMOUNT") {
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") {
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

