On Thu, 2003-07-17 at 10:03, Doug La Farge wrote:
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
                if( $states == "SHIPMENT PACKAGE" ) {
                             ^^
		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]>

Attachment: signature.asc
Description: This is a digitally signed message part

Reply via email to