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.

1
  • Is the data sorted by the group-field? Commented Jun 6, 2013 at 16:09

1 Answer 1

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

Sign up to request clarification or add additional context in comments.

2 Comments

Sorry about the invalid xml, I was typing it out as an example, its not my actual code.
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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.