Solved

Parsing data from a Web Service in PHP

Posted on 2009-05-06
25
230 Views
Last Modified: 2013-12-12
We are trying to set up a web service client in drupal. We got the data pulled in, but it is displaying all the fields instead of just certain ones.  For example I only want to display the 'Degree' and 'AcadPlan' code. I am not really that familiar with pulling XML into a page with php.

Here is a link to what this looks like now.

http://provost-test.asu.edu/node/77

Any help is greatly appreciated!
<?
 

$data = xmlrpc('https://webapp.asu.edu/eadvisor/XmlRpcServer', 'eAdvisorDSFind.findDegreeByCollegeAndProgram', 'CLA' , 'undergrad');
 

$xml = new SimpleXMLElement($data->message);

if($xml){

  $data = $xml->params->param->value->array->data;
 

  foreach($data->value as $degree){

    echo '<ul>';

    foreach($degree->struct->member as $element)

    {

       echo '<li>' . $element->name . ' = ' . $element->value . '</li>';

    }

    echo '</ul><hr>';

  }

}

?>

Open in new window

0
Comment
Question by:SashaIsaac
  • 13
  • 10
  • 2
25 Comments
 
LVL 8

Expert Comment

by:Bobaran98
ID: 24321523
Frankly, I've never done what you're doing.  But it seems to me that you could take that inner foreach statement and do something along the following lines:

foreach($degree->struct->member as $element)
{
if($element->name=="Degree" || $element->name=="AcadPlan")
{
echo '<li>' . $element->name . ' = ' . $element->value . '</li>';
}
}
Does that help?
0
 
LVL 4

Expert Comment

by:aconrad
ID: 24321533
the raw xml source would help
0
 

Author Comment

by:SashaIsaac
ID: 24321844
I know - unfortunately I am not sure how to view the XML through this service. I'll see what the first solutions does and repost. Thanks!
0
 
LVL 4

Expert Comment

by:aconrad
ID: 24322025
this should get you the raw data:

(its the $data->message variable that you give to the SimpleXMLElement class
<?php
 

$data = xmlrpc('https://webapp.asu.edu/eadvisor/XmlRpcServer', 'eAdvisorDSFind.findDegreeByCollegeAndProgram', 'CLA' , 'undergrad');
 

 

echo ($data->message);

Open in new window

0
 

Author Comment

by:SashaIsaac
ID: 24322262
I got it to extract the pieces of data that I need in a table format using the info provided by Bobaran98 -  the link passes the correct variable to the next page which when created will return all the details of that particular major. I tried to sort the info using the code below with no luck. I had used it in another iteration. Do you know how that would work with this scenario?

usort($data,create_function('$a,$b',
  'return strcmp($a["Descr100"],$b["Descr100"]);'));

I will try to extract the XML as well.

Thanks all - very helpful!
<table><?

$group = 'CLA';

$data = xmlrpc('https://webapp.asu.edu/eadvisor/XmlRpcServer', 'eAdvisorDSFind.findDegreeByCollegeAndProgram', $group , 'undergrad');
 

$xml = new SimpleXMLElement($data->message);

if($xml){

  $data = $xml->params->param->value->array->data;
 

usort($data,create_function('$a,$b',

  'return strcmp($a["Descr100"],$b["Descr100"]);'));
 
 

  foreach($data->value as $degree){
 

     

foreach($degree->struct->member as $element)

{
 

if($element->name=="Descr100")

{

echo '<td>' .  $element->value . '</td>';

}
 

if($element->name=="Degree")

{

echo '<td>' .  $element->value . '</td></tr>';

}
 
 

if( $element->name=="AcadPlan")

{
 

echo '<td>' .  '<a href=http://provost-test.asu.edu/testdump&AcadPlan=' . $element->value . ' >' . 'Major Map'  . '</a>'. '</td>';

}
 
 
 

}}}
 

?> </table>

Open in new window

0
 

Author Comment

by:SashaIsaac
ID: 24322311
This page should show the xml in the source:

http://provost-test.asu.edu/node/75


0
 
LVL 8

Expert Comment

by:Bobaran98
ID: 24324888
If it were me, I'd read everything into an array (or multiple arrays), sort the one with the descriptions, and go from there.  Now, in the code below, I'm making the following assumptions:
  • For each Descr100 value, there's exactly one Degree value and one AcadPlan value
  • The Descr100 value comes before the Degree and AcadPlan values
If that's the case, I think the following code should work.  Basically, I use three arrays.  The first has all the descriptions, which can then be alpha sorted.  The Degree and AcadPlan arrays then use the Descr100 value as their key.

If my assumptions aren't valid, see my next two posts.

<?php
 

	//declare array variables

	$arrDesc = new array();

	$arrDegree = new array();

	$arrAcadPlan = new array();
 

	//pull data into arrays

	foreach($data->value as $degree) {

		foreach($degree->struct->member as $element) {

			if($element->name=="Descr100") { 

				array_push($arrDesc, $element->value);

				$thisDesc = $element->value;

			} elseif($element->name=="Degree") {

				$arrDegree[$thisDesc] = $element->value;

			} elseif($element->name=="AcadPlan") {

				$arrAcadPlan[$thisDesc] = $element->value;

			}

		}

	}
 

	//sort description array

	asort($arrDesc);
 

	//spit it all out in a table

	echo "<table>";

	for($i=0;$i<$count($arrDesc);$i++) {

		echo "<tr>";

		echo "	<td>" . $arrDesc[$i] . "</td>";

		echo "	<td><a href='http://provost-test.asu.edu/testdump&AcadPlan=" .		

			$arrAcadPlan[$arrDesc[$i]] . "'>Major Map</a></td>";

		echo "	<td>" . $arrDegree[$arrDesc[$i]] . "</td>";

		echo "</tr>";

	}

	echo "</table>";
 

?>

Open in new window

0
 
LVL 8

Expert Comment

by:Bobaran98
ID: 24324906
Okay now, if there's no guarantee the Descr100 value will appear before the Degree and AcadPlan values, then I've adapted the above code appropriately.  On each iteration, if the Descr100 hasn't yet been found, it saves the Degree and AcadPlan values with a key of "temp", which then gets replaced.

<?php
 

	//declare array variables

	$arrDesc = new array();

	$arrDegree = new array();

	$arrAcadPlan = new array();
 

	//insantiate dummy entries

	$arrDegree["temp"] = "";

	$arrAcadPlan["temp"] = "";
 

	//pull data into arrays

	foreach($data->value as $degree) {

		$thisDesc = "temp";

		foreach($degree->struct->member as $element) {

			if($element->name=="Descr100") { 

				array_push($arrDesc, $element->value);

				$thisDesc = $element->value;

			} elseif($element->name=="Degree") {

				$arrDegree[$thisDesc] = $element->value;

			} elseif($element->name=="AcadPlan") {

				$arrAcadPlan[$thisDesc] = $element->value;

			}

		}

		//if degree grabbed before we knew description

		if($arrDegree <> "") { 

			$arrDegree[$thisDesc] = $arrDegree["temp"];

			$arrDegree["temp"] = "";

		}

		//if acad plan grabbed before we knew description

		if($arrAcadPlan <> "") { 

			$arrAcadPlan[$thisDesc] = $arrAcadPlan["temp"];

			$arrAcadPlan["temp"] = "";

		}

	}
 

	//sort description array

	asort($arrDesc);
 

	//spit it all out in a table

	echo "<table>";

	for($i=0;$i<$count($arrDesc);$i++) {

		echo "<tr>";

		echo "	<td>" . $arrDesc[$i] . "</td>";

		echo "	<td><a href='http://provost-test.asu.edu/testdump&AcadPlan=" .		

			$arrAcadPlan[$arrDesc[$i]] . "'>Major Map</a></td>";

		echo "	<td>" . $arrDegree[$arrDesc[$i]] . "</td>";

		echo "</tr>";

	}

	echo "</table>";
 

?>

Open in new window

0
 
LVL 8

Expert Comment

by:Bobaran98
ID: 24324943
If there's a possibility of a Descr100 value that has less than one Degree or AcadPlan (in other words, if there's an instance where no Degree or AcadPlan exist, perhaps because those fields are optional), you'll need to fix your table output as follows.

<?php
 

	//spit it all out in a table

	echo "<table>";

	for($i=0;$i<$count($arrDesc);$i++) {

		echo "<tr>";

		echo "	<td>" . $arrDesc[$i] . "</td>";
 

		echo "	<td>";

		if(array_key_exists($arrDesc[$i], $arrAcadPlan)) {

			echo "<a href='http://provost-test.asu.edu/testdump&AcadPlan=" .		

				$arrAcadPlan[$arrDesc[$i]] . "'>Major Map</a>";

		}

		echo "	</td>";
 

		echo "	<td>";

		if(array_key_exists($arrDesc[$i], $arrDegree)) {

			echo $arrDegree[$arrDesc[$i]];

		}

		echo "	</td>";
 

		echo "</tr>";

	}

	echo "</table>";
 

?>

Open in new window

0
 
LVL 8

Expert Comment

by:Bobaran98
ID: 24324953
And if there's any possibility of a Descr100 value with more than one Degree or AcadPlan value... well, let me know if that's the case.  At that point we'll need to discuss some two-dimensional arrays.
0
 

Author Comment

by:SashaIsaac
ID: 24328068
I tried the first two  options but at first I got this error:
Parse error: syntax error, unexpected T_ARRAY, expecting T_STRING or T_VARIABLE or '$'

So I searched online and removed the "new" before the array() and then I get this error:
Fatal error: Function name must be a string

I can't seem to figure out what that is referring to.  I searched online and it says something about using an unset variable?

I tried it with and without this around it:

$xml = new SimpleXMLElement($data->message);
if($xml){
  $data = $xml->params->param->value->array->data;

}

Thanks again!
<table>     <?

$group = 'CLA';

$data = xmlrpc('https://webapp.asu.edu/eadvisor/XmlRpcServer', 'eAdvisorDSFind.findDegreeByCollegeAndProgram', $group , 'undergrad');
 

//declare array variables

        $arrDesc =  array();

        $arrDegree =  array();

        $arrAcadPlan =  array();

 

        //insantiate dummy entries

        $arrDegree["temp"] = "";

        $arrAcadPlan["temp"] = "";

 

        //pull data into arrays

        foreach($data->value as $degree) {

                $thisDesc = "temp";

                foreach($degree->struct->member as $element) {

                        if($element->name=="Descr100") { 

                                array_push($arrDesc, $element->value);

                                $thisDesc = $element->value;

                        } elseif($element->name=="Degree") {

                                $arrDegree[$thisDesc] = $element->value;

                        } elseif($element->name=="AcadPlan") {

                                $arrAcadPlan[$thisDesc] = $element->value;

                        }

                }

                //if degree grabbed before we knew description

                if($arrDegree <> "") { 

                        $arrDegree[$thisDesc] = $arrDegree["temp"];

                        $arrDegree["temp"] = "";

                }

                //if acad plan grabbed before we knew description

                if($arrAcadPlan <> "") { 

                        $arrAcadPlan[$thisDesc] = $arrAcadPlan["temp"];

                        $arrAcadPlan["temp"] = "";

                }

        }

 

        //sort description array

        asort($arrDesc);

 

        //spit it all out in a table

        echo "<table>";

        for($i=0;$i<$count($arrDesc);$i++) {

                echo "<tr>";

                echo "  <td>" . $arrDesc[$i] . "</td>";

                echo "  <td><a href='http://provost-test.asu.edu/testdump&AcadPlan=" .          

                        $arrAcadPlan[$arrDesc[$i]] . "'>Major Map</a></td>";

                echo "  <td>" . $arrDegree[$arrDesc[$i]] . "</td>";

                echo "</tr>";

        }

        echo "</table>";
 
 
 

}

?> </table>

Open in new window

0
 
LVL 8

Expert Comment

by:Bobaran98
ID: 24328373
No, I think you need to add the "new" back in for those three declarations.

With a parse error like this, it's good to know the line number.  Can you check it again and then tell me which line of code it's complaining about?

If you're not getting a line number, try the following:

Without touching your existing script, create a brand new php file and call it, say, errors.php.  Save it in the same directory as this page we've been working on.  Within errors.php, include the following code (where mainpage.php is your page that we've been working on):

<?

error_reporting(E_ALL);

ini_set("display_errors",1);

include("mainpage.php");

?>

Open in new window

0
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 
LVL 8

Expert Comment

by:Bobaran98
ID: 24328386
Sorry, posted too quick!  Now just point your browser to this errors.php page, and it should give you any error messages along with the right line numbers.
0
 
LVL 8

Expert Comment

by:Bobaran98
ID: 24328445
Okay, hold up.  I see the problem-- or at least part of it.  Your code won't parse as is because you've got an extra closing curly bracket-- } -- right at the end.  Take that out and try again.
0
 

Author Comment

by:SashaIsaac
ID: 24328955
Drupal is not liking creating that error page - it can be so cumbersome sometimes! But I did get this error listing generated from the actual page:

Parse error: syntax error, unexpected T_ARRAY, expecting T_STRING or T_VARIABLE or '$' in /home/provost/domains/provost-test.asu.edu/public_html/includes/common.inc(1355) : eval()'d code on line 6

So I guess the error is from line 6?

The common.inc file (1353-1359) it is referencing is this function

function drupal_eval($code) {
  ob_start();
  print eval('?>'. $code); //1355
  $output = ob_get_contents();
  ob_end_clean();
  return $output;
}

Thank you!
0
 
LVL 8

Expert Comment

by:Bobaran98
ID: 24329054
Yeah, the problem is most likely not in the common.inc file.  Did you try removing that curly bracket I mentioned in my last post?
0
 

Author Comment

by:SashaIsaac
ID: 24329147
No sorry I hadn't seen that yet. I just did though and get the same error.

Parse error: syntax error, unexpected T_ARRAY, expecting T_STRING or T_VARIABLE or '$' in /home/provost/domains/provost-test.asu.edu/public_html/includes/common.inc(1355) : eval()'d code on line 6

I went ahead and added the code again.
<?

$group = 'CLA';

$data = xmlrpc('https://webapp.asu.edu/eadvisor/XmlRpcServer', 'eAdvisorDSFind.findDegreeByCollegeAndProgram', $group , 'undergrad');

 

//declare array variables

        $arrDesc =  new  array();

        $arrDegree = new array();

        $arrAcadPlan = new array();

 

        //insantiate dummy entries

        $arrDegree["temp"] = "";

        $arrAcadPlan["temp"] = "";

 

        //pull data into arrays

        foreach($data->value as $degree) {

                $thisDesc = "temp";

                foreach($degree->struct->member as $element) {

                        if($element->name=="Descr100") { 

                                array_push($arrDesc, $element->value);

                                $thisDesc = $element->value;

                        } elseif($element->name=="Degree") {

                                $arrDegree[$thisDesc] = $element->value;

                        } elseif($element->name=="AcadPlan") {

                                $arrAcadPlan[$thisDesc] = $element->value;

                        }

                }

                //if degree grabbed before we knew description

                if($arrDegree <> "") { 

                        $arrDegree[$thisDesc] = $arrDegree["temp"];

                        $arrDegree["temp"] = "";

                }

                //if acad plan grabbed before we knew description

                if($arrAcadPlan <> "") { 

                        $arrAcadPlan[$thisDesc] = $arrAcadPlan["temp"];

                        $arrAcadPlan["temp"] = "";

                }

        }

 

        //sort description array

        asort($arrDesc);

 

        //spit it all out in a table

        echo "<table>";

        for($i=0;$i<$count($arrDesc);$i++) {

                echo "<tr>";

                echo "  <td>" . $arrDesc[$i] . "</td>";

                echo "  <td><a href='http://provost-test.asu.edu/testdump&AcadPlan=" .          

                        $arrAcadPlan[$arrDesc[$i]] . "'>Major Map</a></td>";

                echo "  <td>" . $arrDegree[$arrDesc[$i]] . "</td>";

                echo "</tr>";

        }

        echo "</table>";

 

 

 
 

?>

Open in new window

0
 
LVL 8

Expert Comment

by:Bobaran98
ID: 24329297
Okay, I just went through the code line by line, and I think we may have accidentally gotten a new line inserted in the code where it shouldn't have been.  It's hard to see in the code window on this website... I had to copy and paste into an editor to see it.

Try the code below.  The lines that I think were the issue were line numbers 47 and 48 above.

If this doesn't fix it, would you be willing to post or attach the entire file.  Other than the 47/48 thing, I don't see anything else in our excerpt that looks like a problem.

<?

$group = 'CLA';

$data = xmlrpc('https://webapp.asu.edu/eadvisor/XmlRpcServer', 'eAdvisorDSFind.findDegreeByCollegeAndProgram', $group , 'undergrad');

 

//declare array variables

        $arrDesc =  new  array();

        $arrDegree = new array();

        $arrAcadPlan = new array();

 

        //insantiate dummy entries

        $arrDegree["temp"] = "";

        $arrAcadPlan["temp"] = "";

 

        //pull data into arrays

        foreach($data->value as $degree) {

                $thisDesc = "temp";

                foreach($degree->struct->member as $element) {

                        if($element->name=="Descr100") { 

                                array_push($arrDesc, $element->value);

                                $thisDesc = $element->value;

                        } elseif($element->name=="Degree") {

                                $arrDegree[$thisDesc] = $element->value;

                        } elseif($element->name=="AcadPlan") {

                                $arrAcadPlan[$thisDesc] = $element->value;

                        }

                }

                //if degree grabbed before we knew description

                if($arrDegree <> "") { 

                        $arrDegree[$thisDesc] = $arrDegree["temp"];

                        $arrDegree["temp"] = "";

                }

                //if acad plan grabbed before we knew description

                if($arrAcadPlan <> "") { 

                        $arrAcadPlan[$thisDesc] = $arrAcadPlan["temp"];

                        $arrAcadPlan["temp"] = "";

                }

        }

 

        //sort description array

        asort($arrDesc);

 

        //spit it all out in a table

        echo "<table>";

        for($i=0;$i<$count($arrDesc);$i++) {

                echo "<tr>";

                echo "  <td>" . $arrDesc[$i] . "</td>";

                echo "  <td><a href='http://provost-test.asu.edu/testdump&AcadPlan=" . $arrAcadPlan[$arrDesc[$i]] . "'>Major Map</a></td>";

                echo "  <td>" . $arrDegree[$arrDesc[$i]] . "</td>";

                echo "</tr>";

        }

        echo "</table>";

 

 

?>

Open in new window

0
 

Author Comment

by:SashaIsaac
ID: 24329470
I am stumped! It still gives the same error. I can share the drupal site.

Here is the current:

http://provost-test.asu.edu/node/81

Login/pw: admin/change

Then you just hit the edit tab, then under the Body field select "Switch to plain text editor" so you can see the code. Then you submit it at the bottom of the page.

Your help is much appreciated!
0
 
LVL 8

Expert Comment

by:Bobaran98
ID: 24329695
You were on the right track removing the "new" from the array declarations.  Sorry.  Must be confusing my languages.  Anyway, I looked at your site, and I made that change...  Does it look like it's working now?  When I go to "View," it just posts all the code.  Is there a live page you can look at?
0
 

Author Comment

by:SashaIsaac
ID: 24329747
Sorry I should have mentioned underthe switch to plain text editor is the inpit format field link - it was on php, but sometimes it toggles off to full or filtered html. I switched it back to php and now it has the error:

Fatal error: Function name must be a string in /home/provost/domains/provost-test.asu.edu/public_html/includes/common.inc(1355) : eval()'d code on line 44


If you get an error and are locked out of the editing tabs you can go here.

http://provost-test.asu.edu/node/81/edit

Thanks again!
0
 
LVL 8

Accepted Solution

by:
Bobaran98 earned 500 total points
ID: 24330433
Well, my friend, it looks like we've got it. :-)

The main problem -- the reason you were getting that fatal error -- was that at some point some of your XML import code went missing.  Regardless, though, there were a number of other little bugs that needed to be worked through.  One of them was that each time an $element->value was being pushed onto the array, it was going as an XML object rather than a string.  So I created a temp variable that coerced it into a string datatype, then pushed that temp variable onto the array.

Anyway, your only potential issue now is that the page appears a bit slow in loading, but that may have to do with your development environment.  I don't know... maybe it's got to do with the XML stream.  Regardless, I think it would be good if you posted the final PHP code here for sake of posterity (since there's nothing worse than searching a forum, finding a problem just like yours, but not being able to see the solution!).

Also, I suggest you go change your password immediately. :-)
0
 

Author Comment

by:SashaIsaac
ID: 24330540
Thank you so much! I will take a look at the code and try and learn from it. Your rank should be a sage or a genius!

I really appreciate all the time you spent - and I'll change the pw too :)

The solution is included.
<?php

$group = 'CLA';

$data = xmlrpc('https://webapp.asu.edu/eadvisor/XmlRpcServer', 'eAdvisorDSFind.findDegreeByCollegeAndProgram', $group, 'undergrad');

 

$xml = new SimpleXMLElement($data->message);

if($xml){

  $data = $xml->params->param->value->array->data;
 

//declare array variables

        $arrDesc = array();

        $arrDegree = array();

        $arrAcadPlan = array();

	$arrKeys = array();

  

        //pull data into arrays

	$z = 0;

        foreach($data->value as $degree) {

                $thisDesc = "X".$z++;

                foreach($degree->struct->member as $element) {

                        if($element->name=="Descr100") { 

				$tempVal = $element->value." ";

				$arrDesc[$thisDesc] = $tempVal;

                        } elseif($element->name=="Degree") {

                                $arrDegree[$thisDesc] = $element->value;

                        } elseif($element->name=="AcadPlan") {

                                $arrAcadPlan[$thisDesc] = $element->value;

                        }

                }

                //if degree grabbed before we knew description

                if(!array_key_exists($thisDesc, $arrDegree)) { 

                        $arrDegree[$thisDesc] = "";

                } 

                //if acad plan grabbed before we knew description

                if(!array_key_exists($thisDesc, $arrAcadPlan)) { 

                        $arrAcadPlan[$thisDesc] = "";

                } 

        }
 

        //sort description array

        asort($arrDesc);

	$arrKeys = array_keys($arrDesc);
 

        //spit it all out in a table

        echo "<table>";

        for($i=0;$i<count($arrKeys);$i++) {

                echo "<tr>";

                echo "  <td>" . $arrDesc[$arrKeys[$i]] . "</td>";

                echo "  <td><a href='http://provost-test.asu.edu/testdump&AcadPlan=" . $arrAcadPlan[$arrKeys[$i]] . "'>Major Map</a></td>";

                echo "  <td>" . $arrDegree[$arrKeys[$i]] . "</td>";

                echo "</tr>";

        }

        echo "</table>";

 

}
 

?>

Open in new window

0
 

Author Closing Comment

by:SashaIsaac
ID: 31578782
Thanks for your expertise on this problem!
0
 
LVL 8

Expert Comment

by:Bobaran98
ID: 24330587
No problem, it was my pleasure.  But let's hope the next one we tackle isn't so... demanding... ;-)
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

These days socially coordinated efforts have turned into a critical requirement for enterprises.
Password hashing is better than message digests or encryption, and you should be using it instead of message digests or encryption.  Find out why and how in this article, which supplements the original article on PHP Client Registration, Login, Logo…
Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
The viewer will learn how to dynamically set the form action using jQuery.

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now