Connecting Tech Pros Worldwide Forums | Help | Site Map

Parsing XML String (not a Doc) in PHP...Help!

nine72's Avatar
Newbie
 
Join Date: Oct 2006
Location: Carrollton Tx
Posts: 19
#1: Nov 5 '08
Ok, so I have figured out how to parse an custom returned XML doc (actually a string that I made into a doc for testing).

At this point I am attempting to integrate my parse routine into my main code and I am having an issue getting it to mesh, and am looking for a little help in how to 1) combine the two and 2) how to catch the incoming xml string.

FYI the string is sent to me as a return message to an xml message that I send first. (does that make sense)

Here is the how I am parsing the xml code…

[PHP]
<?php
function GetXMLTree ($xmldata)
{
// we want to know if an error occurs
ini_set ('track_errors', '1');

$xmlreaderror = false;

$parser = xml_parser_create ('UTF-8');
xml_parser_set_option ($parser, XML_OPTION_SKIP_WHITE, 1);
xml_parser_set_option ($parser, XML_OPTION_CASE_FOLDING, 0);
/* if (!xml_parse_into_struct ($parser, $xmldata, $vals, $index)) {
$xmlreaderror = true;
echo "error";
}
*/ xml_parser_free ($parser);

if (!$xmlreaderror) {
$result = array ();
$i = 0;
if (isset ($vals [$i]['attributes']))
foreach (array_keys ($vals [$i]['attributes']) as $attkey)
$attributes [$attkey] = $vals [$i]['attributes'][$attkey];

$result [$vals [$i]['tag']] = array_merge ((array)$attributes, (array)GetChildren ($vals, $i, 'open'));

}

ini_set ('track_errors', '0');
return $result;
}

function GetChildren ($vals, &$i, $type)
{
if ($type == 'complete') {
if (isset ($vals [$i]['value']))
return ($vals [$i]['value']);
else
return '';
}

$children = array (); // Contains node data

/* Loop through children */
while ($vals [++$i]['type'] != 'close') {
$type = $vals [$i]['type'];
// first check if we already have one and need to create an array
if (isset ($children [$vals [$i]['tag']])) {
if (is_array ($children [$vals [$i]['tag']])) {
$temp = array_keys ($children [$vals [$i]['tag']]);
// there is one of these things already and it is itself an array
if (is_string ($temp [0])) {
$a = $children [$vals [$i]['tag']];
unset ($children [$vals [$i]['tag']]);
$children [$vals [$i]['tag']][0] = $a;
}
} else {
$a = $children [$vals [$i]['tag']];
unset ($children [$vals [$i]['tag']]);
$children [$vals [$i]['tag']][0] = $a;
}

$children [$vals [$i]['tag']][] = GetChildren ($vals, $i, $type);
} else
$children [$vals [$i]['tag']] = GetChildren ($vals, $i, $type);
// I don't think I need attributes but this is how I would do them:
if (isset ($vals [$i]['attributes'])) {
$attributes = array ();
foreach (array_keys ($vals [$i]['attributes']) as $attkey)
$attributes [$attkey] = $vals [$i]['attributes'][$attkey];
// now check: do we already have an array or a value?
if (isset ($children [$vals [$i]['tag']])) {
// case where there is an attribute but no value, a complete with an attribute in other words
if ($children [$vals [$i]['tag']] == '') {
unset ($children [$vals [$i]['tag']]);
$children [$vals [$i]['tag']] = $attributes;
}
// case where there is an array of identical items with attributes
elseif (is_array ($children [$vals [$i]['tag']])) {
$index = count ($children [$vals [$i]['tag']]) - 1;
// probably also have to check here whether the individual item is also an array or not or what... all a bit messy
if ($children [$vals [$i]['tag']][$index] == '') {
unset ($children [$vals [$i]['tag']][$index]);
$children [$vals [$i]['tag']][$index] = $attributes;
}
$children [$vals [$i]['tag']][$index] = array_merge ($children [$vals [$i]['tag']][$index], $attributes);
} else {
$value = $children [$vals [$i]['tag']];
unset ($children [$vals [$i]['tag']]);
$children [$vals [$i]['tag']]['value'] = $value;
$children [$vals [$i]['tag']] = array_merge ($children [$vals [$i]['tag']], $attributes);
}
} else
$children [$vals [$i]['tag']] = $attributes;
}
}

return $children;
}
?>
[/PHP]


This is where I am reading the current Doc...kind of...

[PHP]

include_once("../class.xmltoarray1.php");

$xmlResponse= "
//.....I have the xml data in here....
";
$contents = ($xmlResponse);

$data = GetXMLTree ($contents);

//and I can print using...
echo "<pre>";
print_r ($data);
echo "</pre>";

[/PHP]


Now, if I do something like this

Expand|Select|Wrap|Line Numbers
  1.          echo "<pre>\n";
  2.             print_r ($xmlResponse);
  3.        echo "</pre>\n";
  4.  
  5.          exit;         
  6.  
  7.  
The response is printed directly to the screen....But there is some serious formating that has to take place so this is not a good option. Also, before asking I do not have a db that I can shove it off into...it is all going into named sessions at this point...see below...

So what I am attempting to do is on the page where I generate the XML that I send I do the following...

[PHP]

//Send XML
$xmlResponse = sendXMLString($xmlString);

//Check for curl error
if ( $xmlResponse == "" )
{
header("Location: " . $GatewaySettings['ErrorPage'] . "?gateway_error=" . rawurlencode("Processing error. Please try again."));
}
else
{ $xmlResponse != "";

$contents = ($xmlResponse);

$data = GetXMLTree ($contents);

// save the generated array to the $_SESSION variable
$_SESSION['xmlResponse'] = $data['NewAdd']['All']['ResponseText'];
//Lots of other sessions being built but will omit for space and read time....
//Redirect to Compete or Faild Page...
if ($_SESSION['xmlResponse'] == "Succeed") {
header('Location:https://192.168.101.169/web_p4/fragments/thankyou.php');
die();
}
else
{
header('Location:http://192.168.101.169/webp4/login.php');
die();
}
}


[/PHP]

Every thing I have tried I am getting no where with...and this last round I get it printed to the screen, comment that out then I get a no database selected error....?!?!?

(yes there is a db that holds the values for the string that I generate and send but not one for me to store the incoming sting in...db guy will not set one up)

I have hit a hard dead line to get this up and going (Nov 14) So any suguestions, assistance etc would be outstanding....

I know that this is a long post but I thank you for getting to the end here...Thanks

code green's Avatar
Expert
 
Join Date: Mar 2007
Location: England
Posts: 1,082
#2: Nov 5 '08

re: Parsing XML String (not a Doc) in PHP...Help!


I am not clear on your exact problem
Quote:
Every thing I have tried I am getting no where with...
and this last round I get it printed to the screen,
comment that out then I get a no database selected error....?!?!?
See my point?
But, this bit doesn't look correct [PHP]else
{ $xmlResponse != "";

$contents = ($xmlResponse); [/PHP] It hurts my head trying to figure out the logic of what WILL happen here
but I would say you've forgot the if() or this was meant to be a comment..
Why do you bracket your variables? I have not come across that anywhere
nine72's Avatar
Newbie
 
Join Date: Oct 2006
Location: Carrollton Tx
Posts: 19
#3: Nov 5 '08

re: Parsing XML String (not a Doc) in PHP...Help!


Sorry about that, did not mean to have the $xmlResponse !=”” in there. I must have left that over in my state of delirium, as well as most of my comments….haha

The issue is that in my testing environment, where I have the xml return string coded between the “ “

1. $xmlResponse= "
2. //..... xml response data here....
3. ";


Everything works fine…

When I attempt to add the xml test code to the project code where the xml response is expected it fails to snag the incoming xml string, parse, create named session and move to the complete page (thankyou.php)

If I comment out the part where I am attempting to parse and have the $xmlResponce print to the screen I can see the string just fine. When I uncomment and try again, I get an error of “No Database Selected” which is odd as I am not making a call to any db at that point.

I will be more than willing to supply the full code set directly to look over.

Thanks

Regards.
code green's Avatar
Expert
 
Join Date: Mar 2007
Location: England
Posts: 1,082
#4: Nov 5 '08

re: Parsing XML String (not a Doc) in PHP...Help!


I suspect problems are arising from this function call
[PHP]$xmlResponse = sendXMLString($xmlString); [/PHP]
Is this a 3rd party function you have borrowed as you do not recognise the errors being generated.
I suggest putting some debugging in the function to see what is happening.
Start by echoing $xmlResponse immediately after the function call [PHP]$xmlResponse = sendXMLString($xmlString);
echo $xmlResponse [/PHP]
nine72's Avatar
Newbie
 
Join Date: Oct 2006
Location: Carrollton Tx
Posts: 19
#5: Nov 5 '08

re: Parsing XML String (not a Doc) in PHP...Help!


Thank you for the suggestion!

I did as directed and then I noticed something in the return string. The person that has written the part I talk to is sending me miss-matched tags and misspelled tags in places…i.e. <state>MD</zip> or <name>FOO</nema>

The error that is being thrown I now find is at the top of my xml generation page where I am building my xml string. The parsing function is calling for an error when it hits the first bad tag and the error message that it is finding to use is in my error routine ergo first error is “No Database Selected”…

I have informed the developer of what I am talking to fix his response code. After the changes maybe it will work right. I will up date the post one way or another.

Oh and just as an FYI, I am not a full time “developer” so my code may be a bit off at times…and I might not be as technical as I need to…But I am the only one in the company that has any experience with PHP or just web in general etc. And Seriusly if I had the funds in my pocket I would hire someone to finish this project... ;)

Thanks!
code green's Avatar
Expert
 
Join Date: Mar 2007
Location: England
Posts: 1,082
#6: Nov 5 '08

re: Parsing XML String (not a Doc) in PHP...Help!


Do not sell yourself short
Quote:
I am not a full time “developer” so my code may be a bit off at times…and I might not be as technical as I need to
You are prepared to at least try to fix it yourself, and are doing alright.
A number of posters come here expecting us to do their work for them.
Good Luck
nine72's Avatar
Newbie
 
Join Date: Oct 2006
Location: Carrollton Tx
Posts: 19
#7: Nov 7 '08

re: Parsing XML String (not a Doc) in PHP...Help!


Ok, they have fixed the tag problems that were there.

So I am up to trying to read the string that is coming in.
At this point I am getting my own error back which is good as it means that I am getting the includes in there and the functions are working. The error however, is telling me that there is nothing for the function to work with…when I attempt a print of what I am expecting it is blank.

So yeah, really need some guidance at this point…

I am posting the code as it is called…

XML generated and this function called for the CURL Session

[php]
<?php

// Gateway cURL Check
function sendXMLString ( &$xmlString )
{
global $GatewaySettings;

$url = $GatewaySettings['url'];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url); // url to connect with
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // return data as string
curl_setopt($ch, CURLOPT_FRESH_CONNECT, 1); // force new connection (not cached)
curl_setopt($ch, CURLOPT_TIMEOUT, 300); // max # secs allowed to execute
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); // allow connection to jetpay w/o verify
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_POST, 1); // set method type to post
curl_setopt($ch, CURLOPT_POSTFIELDS, $xmlString); // set string of data to post

$response = curl_exec($ch); // connect, send, and receive
if (curl_errno($ch))
{
return ("no responce from gateway");
}
else
{
curl_close($ch);
return ($response);
}
}
?>

[/php]

Getting the xml response back...

[php]

$xmlResponse = sendXMLString($xmlString);
[/php]

Dump $xmlResponse to the parser...I Get my error from...
$xmlreaderror = true;
echo "Sorry Man Nothing There To Do";


[php]

<?php
function GetXMLTree ($xmlResponse)
{
// we want to know if an error occurs
ini_set ('track_errors', '1');

$xmlreaderror = false;

$parser = xml_parser_create ('ISO-8859-1');
xml_parser_set_option ($parser, XML_OPTION_SKIP_WHITE, 1);
xml_parser_set_option ($parser, XML_OPTION_CASE_FOLDING, 0);
if (!xml_parse_into_struct ($parser, $ xmlResponse, $vals, $index)) {
$xmlreaderror = true;
echo "Sorry Man Nothing There To Do";
}
xml_parser_free ($parser);

if (!$xmlreaderror) {
$result = array ();
$i = 0;
if (isset ($vals [$i]['attributes']))
foreach (array_keys ($vals [$i]['attributes']) as $attkey)
$attributes [$attkey] = $vals [$i]['attributes'][$attkey];

$result [$vals [$i]['tag']] = array_merge ((array)$attributes, (array)GetChildren ($vals, $i, 'open'));

}

ini_set ('track_errors', '0');
return $result;
}

function GetChildren ($vals, &$i, $type)
{
if ($type == 'complete') {
if (isset ($vals [$i]['value']))
return ($vals [$i]['value']);
else
return '';
}

$children = array (); // Contains node data

// Loop through children
while ($vals [++$i]['type'] != 'close') {
$type = $vals [$i]['type'];
// first check if we already have one and need to create an array
if (isset ($children [$vals [$i]['tag']])) {
if (is_array ($children [$vals [$i]['tag']])) {
$temp = array_keys ($children [$vals [$i]['tag']]);
// there is one of these things already and it is itself an array
if (is_string ($temp [0])) {
$a = $children [$vals [$i]['tag']];
unset ($children [$vals [$i]['tag']]);
$children [$vals [$i]['tag']][0] = $a;
}
} else {
$a = $children [$vals [$i]['tag']];
unset ($children [$vals [$i]['tag']]);
$children [$vals [$i]['tag']][0] = $a;
}

$children [$vals [$i]['tag']][] = GetChildren ($vals, $i, $type);
} else
$children [$vals [$i]['tag']] = GetChildren ($vals, $i, $type);
// I don't think I need attributes but this is how I would do them:
if (isset ($vals [$i]['attributes'])) {
$attributes = array ();
foreach (array_keys ($vals [$i]['attributes']) as $attkey)
$attributes [$attkey] = $vals [$i]['attributes'][$attkey];
// now check: do we already have an array or a value?
if (isset ($children [$vals [$i]['tag']])) {
// case where there is an attribute but no value, a complete with an attribute in other words
if ($children [$vals [$i]['tag']] == '') {
unset ($children [$vals [$i]['tag']]);
$children [$vals [$i]['tag']] = $attributes;
}
// case where there is an array of identical items with attributes
elseif (is_array ($children [$vals [$i]['tag']])) {
$index = count ($children [$vals [$i]['tag']]) - 1;
// probably also have to check here whether the individual item is also an array or not or what... all a bit messy
if ($children [$vals [$i]['tag']][$index] == '') {
unset ($children [$vals [$i]['tag']][$index]);
$children [$vals [$i]['tag']][$index] = $attributes;
}
$children [$vals [$i]['tag']][$index] = array_merge ($children [$vals [$i]['tag']][$index], $attributes);
} else {
$value = $children [$vals [$i]['tag']];
unset ($children [$vals [$i]['tag']]);
$children [$vals [$i]['tag']]['value'] = $value;
$children [$vals [$i]['tag']] = array_merge ($children [$vals [$i]['tag']], $attributes);
}
} else
$children [$vals [$i]['tag']] = $attributes;
}
}

return $children;
}
?>

[/php]

Then to the named session states and the thankyou.php page.

[php]

//Check for curl error
if ( $xmlResponse == "" )
{
header("Location: " . $GatewaySettings['ErrorPage'] . "?gateway_error=" . rawurlencode("Record error. Please try again."));
}
else
{ $contents = ($xmlResponse);

$data = GetXMLTree ($contents);

// save the generated array to the $_SESSION variable
$_SESSION['xmlResponse'] = $data[]NewAdd']['All']['ResponseText'];
$_SESSION['xmlTerBus'] = $data['NewAdd']['All']['Terminals']['Terminal'];
$_SESSION['xmlTerEqp'] = $data['NewAdd']['All']['TerEquipments']['TerEquipment'];
$_SESSION['xmlDefCon'] = $data[NewAdd']['All']['DefaultContact'];
$_SESSION['xmlOpCon'] = $data[‘NewAdd']['All']['OtherContacts']['Contact'];


//Redirect to Compete or Faild Page...
if ($_SESSION['xmlResponse'] == "Succeed") {
header('Location:https://192.168.101.169/web_boarding_p4/fragments/thankyou.php');
die();
}
else
{
header('Location:http://192.168.101.169/web_boarding_p4/login.php');
die();
}
}

[/php]

Any direction would be just, just great at right now…

Thank you.
code green's Avatar
Expert
 
Join Date: Mar 2007
Location: England
Posts: 1,082
#8: Nov 7 '08

re: Parsing XML String (not a Doc) in PHP...Help!


Must confess I am not familiar with curl functions.
But this function does not seem to be working [PHP]function sendXMLString ( &$xmlString ) [/PHP] I would echo out some values in here
In particular, what is being returned from this line[PHP] $response = curl_exec($ch); // connect, send, and receive [/PHP]
nine72's Avatar
Newbie
 
Join Date: Oct 2006
Location: Carrollton Tx
Posts: 19
#9: Nov 7 '08

re: Parsing XML String (not a Doc) in PHP...Help!


I have confirmed that the CURL session is generateing making the connection and sending a well formatted XML to the middleware app.

In the parse routine where I have

1. $xmlreaderror = true;
2. echo "Sorry Man Nothing There To Do";

If I change it to…

[php]
$xmlreaderror = false;
echo "<pre>";
print_r ($xmldata);
echo "</pre>";
}
[/php]

It DOES print out the return string.
Running the return against the schema in Liquid XML Studio it shows that there are no error in the return string…

So somewhere on the parse page I am not getting the string out properly…

To test the actual parse and return I created a test page where I took the string and hard coded it between

$xmldata = “
<return_xml_string_infomration>
” ;

and feed it to the parser and then to the part where I am breaking it out into the named sessions and it runs like a champ…
I print out the named sessions to the screen and it is perfect...

So I wonder if there is a problem between the calls from page to page ie page generateion, curl function page, parse function page, generation page, thank you page…
nine72's Avatar
Newbie
 
Join Date: Oct 2006
Location: Carrollton Tx
Posts: 19
#10: Nov 17 '08

re: Parsing XML String (not a Doc) in PHP...Help!


ok, so after hammering on this for a week now, I am still not getting it to work...

Anyone have any furhter thoughts? If not I guess we can close this out and I will simply let my deadline go...

Thanks for the input.
Reply