【问题标题】:Re-order XML results based on XML data [duplicate]根据 XML 数据重新排序 XML 结果 [重复]
【发布时间】:2013-03-04 14:51:34
【问题描述】:

我们正在通过他们的 API 从远程服务器获取数据。不幸的是,他们的 API 没有按日期对返回的数据进行排序。

我正在尝试弄清楚如何重新组织数据以使其按 next_bookable_date 排序,但没有取得多大成功。我们使用 PHP 和 SimpleXMLElement 来解析数据并创建一个字符串,然后将其插入网页。但当前结果与数据在返回的 XML 中出现的顺序相同。

基本的 XML 结果如下。为了节省空间,我删除了更多数据。

SimpleXMLElement Object
(
    [request] => GET search.xml?start_date=2013-05-03&end_date=2013-05-17
    [error] => OK
    [total_tour_count] => 4
    [tour] => Array
        (
            [0] => SimpleXMLElement Object
                (
                    [next_bookable_date] => 2013-05-13
                    [tour_name] => Thailand Tour
                )
            [1] => SimpleXMLElement Object
                (
                    [next_bookable_date] => 2013-05-12
                    [tour_name] => Bali Tour
                )
            [2] => SimpleXMLElement Object
                (
                    [next_bookable_date] => 2013-05-05
                    [tour_name] => Hawaii Tour
                )
            [3] => SimpleXMLElement Object
                (
                    [next_bookable_date] => 2013-05-06
                    [tour_name] => Bhutan Tour
        )
    )
)

我们用来生成 html 字符串的 PHP 代码(再次剥离了一些 html 代码以节省空间):

foreach($result->tour as $tour) {
$tourname = $tour->tour_name;
$tourdate = $tour->next_bookable_date;

// create string for dpt-soon
$dpt_soon_list .= "<li> some html using the above values </li>\n";
}

有没有办法在我们从远程服务器接收到 XML 数据后重新排序?或者有没有办法在运行 foreach 时重新排序 PHP 输出?

【问题讨论】:

标签: php xml api xml-parsing


【解决方案1】:

您可以使用usort() 对多维数组或对象进行排序。我写了这段代码来解释如何将它与 SimpleXML 一起使用:

<?php
// Load the XML file
$xml = simplexml_load_file("xml.xml");
// Get all children into an array
$Tours = (array)$xml->children();
$Tours = $Tours["tour"];

// Call usort on the array
usort($Tours, "sorttours");

// Output results
echo "<pre>".print_r($Tours, true)."</pre>";

// The function that specifies when an entry is larger, equal or smaller than another
function sorttours($a, $b) {
    // Parse strings into a date for comparison
    $Date1 = strtotime($a->next_bookable_date);
    $Date2 = strtotime($b->next_bookable_date);

    // If equal, return 0
    if ($Date1 == $Date2) {
        return 0;
    }
    // If Date1 is larger, return 1, otherwise -1
    return ($Date1 > $Date2) ? 1 : -1;
}
?>

这个例子假设 XML 看起来有点像这样:

<?xml version="1.0"?>
<tours>
    <tour>
        <next_bookable_date>2013-05-13</next_bookable_date>
        <tour_name>Thailand Tour</tour_name>
    </tour>
    <tour>
        <next_bookable_date>2013-05-12</next_bookable_date>
        <tour_name>Bali Tour</tour_name>
    </tour>
    <tour>
        <next_bookable_date>2013-05-05</next_bookable_date>
        <tour_name>Hawaii Tour</tour_name>
    </tour>
    <tour>
        <next_bookable_date>2013-05-06</next_bookable_date>
        <tour_name>Bhutan Tour</tour_name>
    </tour>
</tours>

如果不是这样,那么您需要重写 sorttours 函数以使用例如属性来确定顺序。

【讨论】:

  • 感谢您为我指明正确的方向。经过一番反复试验,我得到了它的工作。我遇到的一个问题是生成 html 字符串的 foreach。如果 XML 仅包含一个列表,则 usort 将不会创建数组,并且 foreach 将进入无限循环。所以我必须添加一个 if 语句来查看旅游计数,然后选择将其作为 simpleXML 处理或使用 usort 数组路由。
  • 我通常建议改用iterator_to_array,见这里:stackoverflow.com/a/15221083/367456
  • 谢谢@hakre。直到现在才知道这个功能。从现在开始,我将在未来将 iterator_to_array 与 usort 结合使用。一个人永远不会停止学习。
猜你喜欢
  • 2023-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-12
  • 1970-01-01
相关资源
最近更新 更多