Link to home
Start Free TrialLog in
Avatar of SashaIsaac
SashaIsaac

asked on

Parsing data from a Web Service in PHP

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

Avatar of Bobaran98
Bobaran98
Flag of United States of America image

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?
Avatar of aconrad
aconrad

the raw xml source would help
Avatar of SashaIsaac

ASKER

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

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

This page should show the xml in the source:

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


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

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

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

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

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

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.
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.
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!
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?
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

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

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!
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?
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!
ASKER CERTIFIED SOLUTION
Avatar of Bobaran98
Bobaran98
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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

Thanks for your expertise on this problem!
No problem, it was my pleasure.  But let's hope the next one we tackle isn't so... demanding... ;-)