PHP sorting issue with simpleXML

后端 未结 3 1275
挽巷
挽巷 2020-12-12 07:41

test.xml:





    
        a1

        
相关标签:
3条回答
  • 2020-12-12 07:58

    My approach was to convert the SimpleXMLElement objects into arrays:

    $doc = new SimpleXMLElement($xml);
    $states =  get_object_vars($doc->prop->children());
    $states = $states["state"];
    usort($states, function($t1, $t2) { return strcmp($t1['statename'], $t2['statename']); });
    array_walk($states,
        function (&$state) {
            $state = get_object_vars($state);
            array_walk($state["info"],
                function (&$el) {
                    $el = get_object_vars($el);
                }
            );
            usort($state["info"],
                function($a, $b) { return strcmp($a["location"], $b["location"]); }
            );
        }
    );
    
    0 讨论(0)
  • 2020-12-12 08:21

    You want to sort a list of SimpleXMLElements based on some attribute or element value. You normally do this by turning the list into an array and then apply the sorting on that array.

    A function helpful for that in PHP is iterator_to_array. It does the job to turn something that is so magic in simplexml into a more "fixed" array.

    Let's say your tour elements in $result->tour. By default simplexml returns an iterator here, something you can not sort out of the box. Let's convert it into an array:

    $tours = iterator_to_array($result->tour, false);
    

    Now the $tours variable is an array containing each <tour> element as a SimplXMLElement. You can now sort that array with an array function. Those array sorting functions are outlined in the PHP manual and I normally suggest How do I sort a multidimensional array in php as a good starting point:

    $tourDates = array_map(
        function($tour) {return trim($tour->next_bookable_date); },
        $tours
    );
    
    // sort $tours array by dates, highest to lowest
    $success = array_multisort($tourDates, SORT_DESC, $tours);
    

    And that's already it. The whole code at a glance:

    $tours = iterator_to_array($result->tour, false);
    
    $tourDates = array_map(
        function($tour) {return trim($tour->next_bookable_date); },
        $tours
    );
    
    // sort $tours array by dates, highest to lowest
    $success = array_multisort($tourDates, SORT_DESC, $tours);
    
    foreach ($tours as $tour) {
        ...
    }
    
    0 讨论(0)
  • 2020-12-12 08:22

    changing this

    foreach ($prop->children() as $stateattr)
    

    to this

    foreach ($sortedStates as $stateattr)
    

    did it.

    could have sworn I tried that already.

    0 讨论(0)
提交回复
热议问题