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

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • nine72
    New Member
    • Oct 2006
    • 21

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

    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_crea te ('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_int o_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)$attrib utes, (array)GetChild ren ($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.xmltoarra y1.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

    Code:
             echo "<pre>\n";
    			print_r ($xmlResponse);
    	   echo "</pre>\n";
    	
     		exit;
    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("Locatio n: " . $GatewaySetting s['ErrorPage'] . "?gateway_error =" . rawurlencode("P rocessing 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('Locatio n:https://192.168.101.169/web_p4/fragments/thankyou.php');
    die();
    }
    else
    {
    header('Locatio n: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
    Recognized Expert Top Contributor
    • Mar 2007
    • 1726

    #2
    I am not clear on your exact problem
    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

    Comment

    • nine72
      New Member
      • Oct 2006
      • 21

      #3
      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.

      Comment

      • code green
        Recognized Expert Top Contributor
        • Mar 2007
        • 1726

        #4
        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]

        Comment

        • nine72
          New Member
          • Oct 2006
          • 21

          #5
          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!

          Comment

          • code green
            Recognized Expert Top Contributor
            • Mar 2007
            • 1726

            #6
            Do not sell yourself short
            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

            Comment

            • nine72
              New Member
              • Oct 2006
              • 21

              #7
              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 $GatewaySetting s;

              $url = $GatewaySetting s['url'];
              $ch = curl_init();
              curl_setopt($ch , CURLOPT_URL, $url); // url to connect with
              curl_setopt($ch , CURLOPT_RETURNT RANSFER, 1); // return data as string
              curl_setopt($ch , CURLOPT_FRESH_C ONNECT, 1); // force new connection (not cached)
              curl_setopt($ch , CURLOPT_TIMEOUT , 300); // max # secs allowed to execute
              curl_setopt($ch , CURLOPT_SSL_VER IFYPEER, 0); // allow connection to jetpay w/o verify
              curl_setopt($ch , CURLOPT_SSL_VER IFYHOST, 2);
              curl_setopt($ch , CURLOPT_POST, 1); // set method type to post
              curl_setopt($ch , CURLOPT_POSTFIE LDS, $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_crea te ('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_int o_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)$attrib utes, (array)GetChild ren ($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("Locatio n: " . $GatewaySetting s['ErrorPage'] . "?gateway_error =" . rawurlencode("R ecord 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('Locatio n:https://192.168.101.169/web_boarding_p4/fragments/thankyou.php');
              die();
              }
              else
              {
              header('Locatio n:http://192.168.101.169/web_boarding_p4/login.php');
              die();
              }
              }

              [/php]

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

              Thank you.

              Comment

              • code green
                Recognized Expert Top Contributor
                • Mar 2007
                • 1726

                #8
                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]

                Comment

                • nine72
                  New Member
                  • Oct 2006
                  • 21

                  #9
                  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_str ing_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…

                  Comment

                  • nine72
                    New Member
                    • Oct 2006
                    • 21

                    #10
                    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.

                    Comment

                    Working...