排序对象(SimpleXMLElement)php

时间:2013-12-02 23:08:47

标签: php sorting simplexml usort

我正在尝试从SimpleXMLElement中找到一种对数组进行排序的方法。我想按照从event_start_dt获得的开始时间排序。我还想按房间ID排序作为一个单独的过程。目前,数组按对象顺序排列(SimpleXMLElement)#。这是var_dump($ array):

    object(SimpleXMLElement)#275 (1) { 
["reservation"]=> array(3) 
    { 
    [0]=> object(SimpleXMLElement)#287 (28) { 
        ["reservation_id"]=> string(7) "8644894" 
        ["event_start_dt"]=> string(25) "2013-12-02T12:00:00-08:00" 
        ["event_end_dt"]=> string(25) "2013-12-02T13:00:00-08:00" 
        ["event_id"]=> string(6) "314147" 
        ["event_name"]=> string(24) "Practice" 
        ["room_id"]=> string(3) "202"
    }
    [1]=> object(SimpleXMLElement)#288 (28) { 
        ["reservation_id"]=> string(7) "8595185" 
        ["event_start_dt"]=> string(25) "2013-12-02T08:00:00-08:00" 
        ["event_end_dt"]=> string(25) "2013-12-02T09:00:00-08:00" 
        ["event_id"]=> string(6) "314005"
        ["event_name"]=> string(24) "Meeting" 
        ["room_id"]=> string(3) "207"
    }
    [2]=> object(SimpleXMLElement)#289 (28) { 
        ["reservation_id"]=> string(7) "8718654" 
        ["event_start_dt"]=> string(25) "2013-12-02T10:00:00-08:00" 
        ["event_end_dt"]=> string(25) "2013-12-02T11:00:00-08:00" 
        ["event_id"]=> string(6) "315811" 
        ["event_name"]=> string(20) "Maintenance" 
        ["room_id"]=> string(3) "202"
    }
} }

我尝试过usort和asort,但还没有使用任何一种方法。

usort方法:

function sortByTime($a, $b){
    $a = strtotime($array->event_start_dt);
    $b = strtotime($array->event_start_dt);
        if ($a==$b) return 0;
        return ($a < $b) ?-1 : 1;
        }

        usort($arrTimes, 'sortByTime');

        var_dump($arrTimes);

尝试下面的代码会给我警告:usort()期望参数1是数组,给定对象。

foreach ($rez->reservation as $value){ 
    $var1 = $value->space_reservation->space_name;
    $var2 = substr($value->event_start_dt,11,5);
}
sort_obj_arr($value,$var1,SORT_DESC);

echo "<pre>SORTED ";
print_r($value);
echo "</pre>";

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);

}

我有一个来自我的控制器的数组,但是无法工作: 我得到:usort()期望参数1是数组,给定对象或null。

$array = array($this->data);
print_r($array);

array(1) { 
[0]=> object(SimpleXMLElement)#280 (1) { ["reservation"]=> array(3) { 
        [0]=> object(SimpleXMLElement)#287 (28) { 
            ["reservation_id"]=> string(7) "8644894" 
            ["event_start_dt"]=> string(25) "2013-12-02T12:00:00-08:00" 
            ["event_end_dt"]=> string(25) "2013-12-02T13:00:00-08:00" 
            ["event_id"]=> string(6) "314147" 
            ["event_name"]=> string(24) "Practice" 
            ["room_id"]=> string(3) "202"
        }
        [1]=> object(SimpleXMLElement)#288 (28) { 
            ["reservation_id"]=> string(7) "8595185" 
            ["event_start_dt"]=> string(25) "2013-12-02T08:00:00-08:00" 
            ["event_end_dt"]=> string(25) "2013-12-02T09:00:00-08:00" 
            ["event_id"]=> string(6) "314005"
            ["event_name"]=> string(24) "Meeting" 
            ["room_id"]=> string(3) "207"
        }
        [2]=> object(SimpleXMLElement)#289 (28) { 
            ["reservation_id"]=> string(7) "8718654" 
            ["event_start_dt"]=> string(25) "2013-12-02T10:00:00-08:00" 
            ["event_end_dt"]=> string(25) "2013-12-02T11:00:00-08:00" 
            ["event_id"]=> string(6) "315811" 
            ["event_name"]=> string(20) "Maintenance" 
            ["room_id"]=> string(3) "202"
        }
    } }

请求print_r:

SimpleXMLElement Object
(
    [reservation] => Array(3)
        (
            [0] => SimpleXMLElement Object
                (
                    [reservation_id] => 8604174
                    [event_start_dt] => 2013-12-31T06:00:00-08:00
                    [event_end_dt] => 2013-12-31T08:00:00-08:00
                    [event_id] => 314147
                    [event_name] => Practice
                    [room_id] => 202
                 )
         [1] => SimpleXMLElement Object
                (
                    [reservation_id] => 8604177
                    [event_start_dt] => 2013-12-31T05:00:00-08:00
                    [event_end_dt] => 2013-12-31T06:00:00-08:00
                    [event_id] => 314150
                    [event_name] => Meeting
                    [room_id] => 216
                 )
         [2] => SimpleXMLElement Object
                (
                    [reservation_id] => 8604189
                    [event_start_dt] => 2013-12-31T10:00:00-08:00
                    [event_end_dt] => 2013-12-31T11:00:00-08:00
                    [event_id] => 314150
                    [event_name] => Maintenance
                    [room_id] => 220
                 )
)
)

$arrTimes = xml2array($array->reservation);

var_dump($arrTimes)

array(5) { 
["reservation_id"]=> string(7) "8604175" 
["event_start_dt"]=> string(25) "2014-01-02T06:00:00-08:00" 
["event_end_dt"]=> string(25) "2014-01-02T08:00:00-08:00" 
["event_id"]=> string(6) "314147" 
["event_name"]=> string(24) "Practice" 
}

4 个答案:

答案 0 :(得分:2)

使用 array_multisort

            foreach ($rez->reservation as $value)
            { 
                     $dateTime[] = $value->event_start_dt;
            }

           array_multisort($dateTime,SORT_ASC,SORT_STRING,$rez->reservation);   
           echo "<pre>";
           print_r($rez->reservation);

检查一下。这是我的代码

<?php
        $myarray=array(
                    0 => array
                        (
                            'dateTime' => '2013-12-02T10:00:00-08:00',
                            'chanl1' => '20.10',
                            'chanl2' => '45.4',
                            'chanl3' => '',
                        ),

                    1 => array
                        (
                            'dateTime' => '2013-12-02T11:00:00-08:00',
                            'chanl1' => '20.11',
                            'chanl2' => '45.4',
                            'chanl3' => '',
                        ),
                  2 => array
                        (
                            'dateTime' => '2013-12-02T12:00:00-08:00',
                            'chanl1' => '20.12',
                            'chanl2' => '33.8',
                            'chanl3' => '',
                        ),

                    3 => array
                        (
                            'dateTime' => '2013-12-02T09:00:00-08:00',
                            'chanl1' => '20.9',
                            'chanl2' => '33.9',
                            'chanl3' => ''
                        ));

            foreach($myarray as $c=>$key) {
                    $dateTime[] = $key['dateTime'];                      
            }           


        array_multisort($dateTime,SORT_ASC,SORT_STRING,$myarray);   
        echo "<pre>";
        print_r($myarray);
        ?>

输出是:

Array
(
    [0] => Array
        (
            [dateTime] => 2013-12-02T09:00:00-08:00
            [chanl1] => 20.9
            [chanl2] => 33.9
            [chanl3] => 
        )

    [1] => Array
        (
            [dateTime] => 2013-12-02T10:00:00-08:00
            [chanl1] => 20.10
            [chanl2] => 45.4
            [chanl3] => 
        )

    [2] => Array
        (
            [dateTime] => 2013-12-02T11:00:00-08:00
            [chanl1] => 20.11
            [chanl2] => 45.4
            [chanl3] => 
        )

    [3] => Array
        (
            [dateTime] => 2013-12-02T12:00:00-08:00
            [chanl1] => 20.12
            [chanl2] => 33.8
            [chanl3] => 
        )

)

<强> FIDDLE

答案 1 :(得分:1)

在对数据进行排序之前,您需要创建一个数组,其中包含要排序的单独项目作为其值。从您的调试输出中,这些是输入XML中的多个<reservation>节点,这些节点是这些样本中由$array / $this->data表示的元素的子节点(如果不重要它是否是文档的根,SimpleXML没有Document对象。)

您的print_rvar_dump输出显示您当前没有这样的数组,只有SimpleXML对象:

  • 您的第一个示例显示var_dump($array)提供输出开始object(SimpleXMLElement)#275 (1) { - 忽略array一词,这就是var_dump呈现的方式内部对象。
  • 稍后,您有一个print_r($array);开始array(1) { - 但这只是因为您已将实际数据包装在上一行的单元素数组中($array = array($this->data); )并且一个元素($array[0])显示为object(SimpleXMLElement)#280 (1) { ...

请注意,没有必要进一步将所有内部SimpleXML对象转换为数组 - 您只需要一个可排序的列表,其中包含您感兴趣的项目。我个人会使用简单明了的foreach循环,以获得最大的代码可读性,尽管&#34;更聪明&#34;提供解决方案。

一旦有了可排序列表,就需要usort的回调函数来比较它的两个参数。您所做的尝试是沿着正确的方向,但是指的是不存在的(在该函数中)变量$array;您需要比较的值是函数的参数,您称之为$a$b - 具体而言,您希望将strtotime($a->event_start_dt)与{{1}进行比较}。

您还可以使函数更简单,因为它遵循常见的误解,即回调的返回值应为strtotime($b->event_start_dt)-10。事实上,它可以是任何整数,只有它的符号很重要 - 返回1将与返回-42具有相同的效果,即将-999项放在$a之前结果数组。

我无法轻松提供经过测试的示例,因为您还没有提供基础XML来重现您的输入(例如$b),但我将采取的基本方法是:

echo $this->data->asXML();

答案 2 :(得分:0)

我只是使用此函数将其转换为数组(来自php.net的示例函数)。但请注意,这不会对XML进行排序,而是对新数组进行排序

/**
* function xml2array
*
* This function is part of the PHP manual.
*
* The PHP manual text and comments are covered by the Creative Commons 
* Attribution 3.0 License, copyright (c) the PHP Documentation Group
*
* @author  k dot antczak at livedata dot pl
* @date    2011-04-22 06:08 UTC
* @link    http://www.php.net/manual/en/ref.simplexml.php#103617
* @license http://www.php.net/license/index.php#doc-lic
* @license http://creativecommons.org/licenses/by/3.0/
* @license CC-BY-3.0 <http://spdx.org/licenses/CC-BY-3.0>
*/
function xml2array ( $xmlObject, $out = array () )
{
  foreach ( (array) $xmlObject as $index => $node )
    $out[$index] = ( is_object ( $node ) ) ? xml2array ( $node ) : $node;

   return $out;
 }

并传递XMLObject

$arrTimes = xml2array(YourSimpleXMLElement);

然后在新数组上使用原始的usort函数

 function sortByTime($a, $b){
    $a = strtotime($a['event_start_dt']);
    $b = strtotime($b['event_start_dt']);
    if ($a==$b) 
       return 0;
    return ($a < $b) ? -1 : 1;
 }

最后

usort($arrTimes, 'sortByTime');

答案 3 :(得分:-1)

您必须使用json encode decode

将frist in转换为xml到数组

$ xml_array = json_decode(json_encode((array)$ xml),TRUE);

你将得到数组的列表....比你可以根据日期使用strtotime函数获得sory。