You are here:  » How to group results based on a xml field


How to group results based on a xml field

Submitted by gediweb on Mon, 2009-12-21 20:13 in

Hi,

I was able to display my XML based on the BBC News example. Formats, links and displays great, but right now all the results come in together in one long list.

I have an XML of Junior Tennis ranking results grouped by class value. How would I go about grouping the results by the correct class value with a "class of whatever year" as a header over each one?

Here is my xml, or part of it anyway, because it is too long.

{code saved}

Submitted by support on Mon, 2009-12-21 20:32

Hi there,

What I would do in this instance is populate a global array of records; keyed by CLASS-VALUE. You can then loop through that array; create the appropriate heading and then use a second display "record handler" function containing the same code as your myRecordHandler function from your working test script to actually display the records. For example (replace filename.xml, xml|FORMAT/STRING etc. with the correct values from your working test script):

<?php
  
require("MagicParser.php");
  
$allRecords = array();
  function 
myRecordHandler($record)
  {
    global 
$allRecords;
    
$allRecords[$record["CLASS-VALUE"]][] = $record;
  }
  
MagicParser_parse("filename.xml","myRecordHandler","xml|FORMAT/STRING");
  function 
myDisplayRecordHandler($record)
  {
    
// same code here as your working myRecordHandler function
  
}
  foreach(
$allRecords as $year => $records)
  {
    print 
"<h2>Class of ".$year."</h2>";
    foreach(
$records as $record)
    {
      
myDisplayRecordHandler($record);
    }
  }
?>

Hope this helps!
Cheers,
David.

Submitted by gediweb on Mon, 2009-12-21 21:41

Thank you for your reply. Here is the code that I have (below) and here is a link to the results: http://portico1.com/test/MagicParserTest.php
They are basically displaying as they did before. Nothing changed. And the class of: does not recognize the $year

 <?php
  require("MagicParser.php");
  $allRecords = array();
  function myRecordHandler($record)
  {
    global $allRecords;
    $allRecords[$record["CLASS-VALUE"]][] = $record;
  }
  $url = "http://www.tennisrecruiting.net/xml/boys/top10.xml";
  MagicParser_parse($url,"myRecordHandler");
  function myDisplayRecordHandler($record)
  {
    print "<table width='20%' border='0' cellspacing='0' cellpadding='0'><tr><td width='20%' valign='top'>".$record["RANK"]."</td>";
    print "<td width='80%' align='left' valign='top'><B><a href='".$record["URL"]."'>".$record["FIRSTNAME"]."&nbsp;".$record["LASTNAME"]."</a></B><BR>State:".$record["STATE"]."<BR><BR></td>
  </tr>
</table>";
  }
  foreach($allRecords as $year => $records)
  {
    print "<h2>Class of ".$year."</h2>";
    foreach($records as $record)
    {
      myDisplayRecordHandler($record);
    }
  }
?>

Submitted by support on Mon, 2009-12-21 22:05

Hi,

My apologies - i'd mis-interpreted the way the class was represented in your XML. I checked the actual feed; and since it is at a higher level in the document a slightly different method will actually be required.

The trick in this case is to first parse your XML at the RANKINGS/GENDER/CLASS/ level in order to build up an array ($classIds) mapping a PLAYERID to their class.

Next, the feed is parsed at the RANKINGS/GENDER/CLASS/PLAYER/ level and as before build up an array indexed by class; but in this case getting class from the $classIds array built up in the first parse.

Have a go with something like this...

<?php
  
require("MagicParser.php");
  
$url "http://www.tennisrecruiting.net/xml/boys/top10.xml";
  
$xml file_get_contents($url);
  
$classIds = array();
  
$allRecords = array();
  function 
myClassRecordHandler($record)
  {
    global 
$classIds;
    foreach(
$record as $k => $v)
    {
      if (
strpos($k,"PLAYERID"))
      {
        
$classIds[$v] = $record["CLASS-VALUE"];
      }
    }
  }
  
MagicParser_parse("string://".$xml,"myClassRecordHandler","xml|RANKINGS/GENDER/CLASS/");
  function 
myPlayerRecordHandler($record)
  {
    global 
$classIds;
    global 
$allRecords;
    
$allRecords[$classIds[$record["PLAYERID"]]][] = $record;
  }
  
MagicParser_parse("string://".$xml,"myPlayerRecordHandler","xml|RANKINGS/GENDER/CLASS/PLAYER/");
  function 
myDisplayRecordHandler($record)
  {
    print 
"<table width='20%' border='0' cellspacing='0' cellpadding='0'><tr><td width='20%' valign='top'>".$record["RANK"]."</td>";
    print 
"<td width='80%' align='left' valign='top'><B><a href='".$record["URL"]."'>".$record["FIRSTNAME"]."&nbsp;".$record["LASTNAME"]."</a></B><BR>State:".$record["STATE"]."<BR><BR></td></tr></table>";
  }
  foreach(
$allRecords as $year => $records)
  {
    print 
"<h2>Class of ".$year."</h2>";
    foreach(
$records as $record)
    {
      
myDisplayRecordHandler($record);
    }
  }
?>

Hope this helps!
Cheers,
David.

Submitted by gediweb on Wed, 2009-12-23 20:49

That's perfect David! Thank you!!!!