PHP sorting issue with simpleXML

Posted by tugbucket on Stack Overflow See other posts from Stack Overflow or by tugbucket
Published on 2010-06-11T13:18:04Z Indexed on 2010/06/11 13:33 UTC
Read the original article Hit count: 340

Filed under:
|

test.xml:

<?xml version="1.0"?>
<props>
<prop>
<state statename="Mississippi">
    <info>
        <code>a1</code>
        <location>Jackson</location>
    </info>
    <info>
        <code>d2</code>
        <location>Gulfport</location>
    </info>
    <info>
        <code>g6</code>
        <location>Hattiesburg</location>
    </info>
</state>
<state statename="Texas">
    <info>
        <code>i9</code>
        <location>Dallas</location>
    </info>
    <info>
        <code>a7</code>
        <location>Austin</location>
    </info>
</state>
<state statename="Maryland">
    <info>
        <code>s5</code>
        <location>Mount Laurel</location>
    </info>
    <info>
        <code>f0</code>
        <location>Baltimore</location>
    </info>
    <info>
        <code>h4</code>
        <location>Annapolis</location>
    </info>
</state>
</prop>
</props>

test.php

// start the sortCities
function sortCities($a, $b){
    return strcmp($a->location, $b->location);
}
// start the sortStates
function sortStates($t1, $t2) {
    return strcmp($t1['statename'], $t2['statename']);
}


$props = simplexml_load_file('test.xml');
foreach ($props->prop as $prop) {
    $sortedStates = array();
    foreach($prop->state as $states) {
        $sortedStates[] = $states;
        }
    usort($sortedStates, "sortStates"); // finish the sortStates
    /* --- */
    echo '<pre>'."\n";
    print_r($sortedStates);
    echo '</pre>'."\n"; 
    /* --- */
    foreach ($prop->children() as $stateattr) { // this doesn't do it
    //foreach($sortedStates as $hotel => @attributes){ // blargh!
        if(isset($stateattr->info)) {
            $statearr = $stateattr->attributes();
            echo '<optgroup label="'.$statearr['statename'].'">'."\n";
            $options = array();
            foreach($stateattr->info as $info) {
                $options[] = $info;                            
            }
            usort($options, "sortCities"); // finish the sortCities  
            foreach($options as $stateattr => $info){
                echo '<option value="'.$info->code.'">'.$info->location.'</option>'."\n";
            }
            echo '</optgroup>'."\n";
            } else {
                //empty nodes don't do squat
            }
    }
}  
?>

This is the array that:

print_r($sortedStates);

prints out:

Array
(
    [0] => SimpleXMLElement Object
        (
            [@attributes] => Array
                (
                    [statename] => Maryland
                )

            [info] => Array
                (
                    [0] => SimpleXMLElement Object
                        (
                            [code] => s5
                            [location] => Mount Laurel
                        )

                    [1] => SimpleXMLElement Object
                        (
                            [code] => f0
                            [location] => Baltimore
                        )

                    [2] => SimpleXMLElement Object
                        (
                            [code] => h4
                            [location] => Annapolis
                        )

                )

        )

    [1] => SimpleXMLElement Object
        (
            [@attributes] => Array
                (
                    [statename] => Mississippi
                )

            [info] => Array
                (
                    [0] => SimpleXMLElement Object
                        (
                            [code] => a1
                            [location] => Jackson
                        )

                    [1] => SimpleXMLElement Object
                        (
                            [code] => d2
                            [location] => Gulfport
                        )

                    [2] => SimpleXMLElement Object
                        (
                            [code] => g6
                            [location] => Hattiesburg
                        )

                )

        )

    [2] => SimpleXMLElement Object
        (
            [@attributes] => Array
                (
                    [statename] => Texas
                )

            [info] => Array
                (
                    [0] => SimpleXMLElement Object
                        (
                            [code] => i9
                            [location] => Dallas
                        )

                    [1] => SimpleXMLElement Object
                        (
                            [code] => a7
                            [location] => Austin
                        )

                )

        )

)

this:

// start the sortCities
function sortCities($a, $b){
    return strcmp($a->location, $b->location);
}

plus this part of code:

    $options = array();
    foreach($stateattr->info as $info) {
        $options[] = $info;                            
    }
    usort($options, "sortCities"); // finish the sortCities  
    foreach($options as $stateattr => $info){
        echo '<option value="'.$info->code.'">'.$info->location.'</option>'."\n";
    }

is doing a fine job of sorting by the 'location' node within each optgroup.

You can see that in the array I can make it sort by the attribute 'statename'. What I am having trouble with is echoing out and combining the two functions in order to have it auto sort both the states and the cities within and forming the needed optgroups.

I tried copying the lines for the cities and changing the names called several ways to no avail.

© Stack Overflow or respective owner

Related posts about php

Related posts about simplexml