Rob
Rob

Reputation: 79

How to Parse XML style HTTP Post Return to Variables or Array with PHP 5.1.6

I have three possible HTTP Post returns that I'm trying to get an Array out of with PHP 5.1.6. I'm not exactly sure on the terminology of this (sorry).

<?PHP
// Values the $var could be:
$var = "<STATUS>SUCCESS</STATUS><BR><TIME>Mon Oct 17 20:44:41 PDT 2011</TIME>"; 
// OR
$var = "<STATUS>REJECTED</STATUS>"; 
// OR
$var = "<STATUS>ERROR</STATUS></BR><VALIDATION MESSAGE>200-Service and Zipcode is required.</VALIDATION MESSAGE> ";

// Output I'd like to see:
$array = Array ( 
            ['STATUS'] => 'SUCCESS', 
            ['TIME'] => 'Mon Oct 17 20:44:41 PDT 2011',
            ['VALIDATION MESSAGE'] => '' 
        );
// OR
$array = Array ( 
            ['STATUS'] => 'REJECTED', 
            ['TIME'] => '',
            ['VALIDATION MESSAGE'] => '' 
        );
//OR
$array = Array ( 
            ['STATUS'] => 'ERROR', 
            ['TIME'] => '',
            ['VALIDATION MESSAGE'] => '200-Service and Zipcode is required.' 
        );

//Another way to look at the desired output array would be:
/*    
  Array
        (
            [STATUS] => SUCCESS
            [TIME] => Mon Oct 17 20:44:41 PDT 2011
            [VALIDATION MESSAGE] => 
        )
// OR
  Array
        (
            [STATUS] => REJECTED
            [TIME] => 
            [VALIDATION MESSAGE] => 
        )
// OR 
  Array
        (
            [STATUS] => ERROR
            [TIME] => Mon Oct 17 20:44:41 PDT 2011
            [VALIDATION MESSAGE] => 
        )
*/
?>

Maybe a preg_match or ??? (preg_match is still a little baffling to me at this point) I've been spinning my wheels thus far.

Thanks!

Upvotes: 1

Views: 172

Answers (3)

Len
Len

Reputation: 542

I'm correcting the regex to cover each situation. All you have to do now is create a case statement that will fill the fields of your array.

$regex = "/<(STATUS)>(.*)<\/STATUS>(?:<\/?BR>)?(?:<(TIME)>(.*)<\/TIME>)?(?:<(VALIDATION MESSAGE)>(.*)<\/VALIDATION MESSAGE>)?/";

preg_match($regex, $var, $m);


print_r($res)

// Simply create an empty associative array with the fields you need,defaulting        everything to '', then write a switch statement based on the sizeof($m) and assign the fields. Each case produces a different count.

Results of regex against your three strings...

Array ( [0] => SUCCESS
Mon Oct 17 20:44:41 PDT 2011 [1] => STATUS [2] => SUCCESS [3] => TIME [4] => Mon Oct  17 20:44:41 PDT 2011 )

Array ( [0] => REJECTED [1] => STATUS [2] => REJECTED )

Array ( [0] => ERROR
200-Service and Zipcode is required. [1] => STATUS [2] => ERROR [3] => [4] => [5]  =>    VALIDATION MESSAGE [6] => 200-Service and Zipcode is required. ) 

If an answer does indeed solve your issue, please increment the counter on the left.

Upvotes: 0

Rob
Rob

Reputation: 79

I used hakre's solution in conjunction with an if/else to pull the desired outputs. I did leave out the full 3 variable array but it could easily be added... I decided I didn't need the extra empty variables. I'm SURE there is a more elegant method BUT this is the best I've come up with so far. Thanks to hakre & Len for helping me figure this out!! Here's the code:

<?
# NOTES:
# This is just demo code to test if the code works.
# The echo/print code is just to show me what's going on as the script processes

    # SIMULATED (Manual) HTTP Post Response Variable
    # uncomment each to test
    $var = "<STATUS>SUCCESS</STATUS><BR><TIME>Mon Oct 17 20:44:41 PDT 2011</TIME>";
    // OR
    #$var = "<STATUS>REJECTED</STATUS>"; 
    // OR
    #$var = "<STATUS>ERROR</STATUS><BR><VALIDATION MESSAGE>100-Invalid Username and Password.</VALIDATION MESSAGE>";
    // OR
    #$var = "<STATUS>Unknown Value</STATUS><BR><WHO KNOWS>Uncaptured</WHO KNOWS>";

    $arrayPRE = array_combine
    (
        array('STATUS'), 
        sscanf($var, '<STATUS>%[^<]</STATUS>')
    );

    echo 'arrayPRE:<pre>';
    print_r($arrayPRE);
    echo '</pre><hr>';

if ($arrayPRE['STATUS']=='SUCCESS'){

    $array = array_combine
        (
            array('STATUS', 'TIME'), 
            sscanf($var, '<STATUS>%[^<]</STATUS><BR><TIME>%[^<]</TIME>')
        );
    echo 'SUCCESS<pre>';
    print_r($array);
    echo '</pre>';

}elseif($arrayPRE['STATUS']=='REJECTED'){

    $array = array_combine
        (
            array('STATUS'), 
            sscanf($var, '<STATUS>%[^<]</STATUS>')
        );
    echo 'REJECTED<pre>';
    print_r($array);
    echo '</pre>';

}elseif($arrayPRE['STATUS']=='ERROR'){

    $array = array_combine
        (
            array('STATUS', 'VALIDATION MESSAGE'), 
            sscanf($var, '<STATUS>%[^<]</STATUS><BR><VALIDATION MESSAGE>%[^<]</VALIDATION MESSAGE>')
        );
    echo 'ERROR<pre>';
    print_r($array);
    echo '</pre>';

}else{
    //unknown Response - ALERT ADMIN / SEND and RECORD $var
    echo 'Unknown Response<br>';
    echo htmlspecialchars($var);// making the code readable in a browser
}//end if ($arrayPRE['STATUS']==''{


?>

Upvotes: 0

hakre
hakre

Reputation: 198204

As you have a simple pattern, you can just parse it with sscanf and assign it to the array keys:

$var = "<STATUS>SUCCESS</STATUS><BR><TIME>Mon Oct 17 20:44:41 PDT 2011</TIME>";

$r = sscanf($var, '<STATUS>%[^<]</STATUS><BR><TIME>%[^<]</TIME>', 
            $array['STATUS'], $array['TIME']);

$array:

Array
(
    [STATUS] => SUCCESS
    [TIME] => Mon Oct 17 20:44:41 PDT 2011
)

Demo / Demo (old)

Upvotes: 1

Related Questions