0

Main Idea: Using Simple XML I want to be able to group my data based upon one of the attributes.

An example of my data set up (simplified):

[Entry]
[Entry Id]1[/Entry Id]
[Field 1]First Name[/Field 1]
[Field 2]Last Name[/Field 2]
[Field 3]Grade[/Field 3]
[/Entry]

Taking the above example I am currently using SimpleXML to search for one grade (ie 8th) and then listing each entry's Name below it giving me something like:

**8th Grade**
Jon Doe
Jane Smith

And so on. The only problem with this is I am creating a "foreach" statement for each grade I want to display.

I believe there has to be a way to just have one statement that spits out the names of each person grouped by grade without having to go in each time I want to add a new grade and manually typing a "foreach" statement.

I am a total newb at PHP so any examples or explanations you can give would be hugely helpful.

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
hanster
  • 17
  • 2

1 Answers1

0

EDIT: to group, first sort it, then output it.
Credits: Function sort_obj_arr written by [GZipp][1] in this post.

// define it
$xml = simplexml_load_string($x); // assuming XML in $x
$grades = $xml->xpath("//Entry"); 

// sort it
sort_obj_arr($grades,'Field_3',SORT_ASC);

// print it
$g = "";
foreach ($grades as $grade) {
if ($grade->Field_3 <> $g) {    
        $g = (string)$grade->Field_3;
    echo "<br />*** grade $g ***<br />";
}
echo $grade->Field_1 . " " . $grade->Field_2 . "<br />";
}

// function for sorting
function sort_obj_arr(& $arr, $sort_field, $sort_direction) {
    $sort_func = function($obj_1, $obj_2) use ($sort_field, $sort_direction) {
        if ($sort_direction == SORT_ASC) {
            return strnatcasecmp($obj_1->$sort_field, $obj_2->$sort_field);
        } else {
            return strnatcasecmp($obj_2->$sort_field, $obj_1->$sort_field);
        }
    };
    usort($arr, $sort_func);
}

see it working: http://codepad.viper-7.com/Saka16

to start with: your XML is invalid, you need <> and no spaces in node names:

<Entries>
    <Entry>
        <Entry_Id>1</Entry_Id>
        <Field_1>John</Field_1>
        <Field_2>Doe</Field_2>
        <Field_3>8</Field_3>
    </Entry>
</Entries>

to select nodes with a certain value, use xpath:

$xml = simplexml_load_string($x); // assuming XML in $x
$grades = $xml->xpath("//Entry[Field_3 = '8']");

echo "** grade: " . $grades[0]->Field_3 . "**<br />";

foreach ($grades as $grade) {

    echo $grade->Field_1 . " " . $grade->Field_2 . "<br />";

}

see it working: http://codepad.viper-7.com/Lke7gc

Community
  • 1
  • 1
michi
  • 6,565
  • 4
  • 33
  • 56
  • Sorry about the invalid xml, I was typing it out as an example, its not my actual code. – hanster Jun 05 '13 at 17:24
  • Ok, so this does what I am already doing, what I want is the next step where instead of identifying all records with "8th Grade" I want the xml to spit out each grade with their corresponding records. So if I have 24 entries (2 of each grade) I get all 12 grades with those students underneath their respective grades. Hopefully that is not confusing. – hanster Jun 05 '13 at 17:26