1

我正在尝试遍历一些 JSON 数据并提取特定值。这是 JSON 数据和部分工作的代码。

$jsondata = '
[
  {
  "id" : "421356",
  "trip_update" : {
    "trip" : {
      "trip_id" : "421356",
      "start_time" : "12:05:00",
      "start_date" : "20130926",
      "route_id" : "15"
    },
    "stop_time_update" : {
       "stop_sequence" :70,
      "departure" : {
        "delay" : 240,
        "time" : 1380215057
      },
      "stop_id" : "6090"
    },
    "stop_time_update" : {
       "stop_sequence" :71,
      "departure" : {
        "delay" : 240,
        "time" : 1380215075
      },
      "stop_id" : "6095"
    }
  }
}]';
$result = json_decode($jsondata);

foreach($result as $value) {
  echo "trip_id: ".$value->trip_update->trip->trip_id;
  if (gettype($value->trip_update ) == "object") {
    foreach($value->trip_update as $item) {
       echo " - stop_sequence: ".$item->stop_sequence;
    }
  }
}

我可以在“trip_update->trip”下获得第一级数据。但在“trip_update”中也可以有任意数量的“stop_time_update”数据。由于此数据与 trip_update 数据相关,因此我需要遍历它并关联它。

最终目标是将此数据保存到数据库(代码中未显示),因此为清楚起见,这将是我想在此示例中保存的简化的 2 行数据库数据:

trip_id,stop_sequence
421356,70
421356,71

源数据中可以有任意数量的 stop_sequence。

这是代码的交互式链接,供您编辑或弄乱: http ://sandbox.onlinephpfunctions.com/code/f21ca8928da7de3e9fb351edb075d0a446906937

4

4 回答 4

2

如果您编写自己的解析器或使用带有回调的流解析器,您可能会得到更好的结果。这是这样一个与回调一起工作的解析器的PHP 实现。因此,解析器不会将整个 JSON 数据读入内存,而是会以块的形式读取数据,并在新对象启动或读入属性等时通知您的“侦听器类”。通过这样做,您应该获得单独的回调事件对于每个stop_time_update属性,而不仅仅是解析数组中的一个值。

非常类似于用于 XML 的SAX 。

于 2013-09-26T20:50:27.087 回答
1

你应该重做你的 JSON - 你有多个同名的键,试着print_r($result)看看我在说什么 - PHP 将一次又一次地覆盖“stop_time_update”键,你将只能访问最后一个条目。相反,您应该像这样组织您的 JSON:

[
  {
  "id" : "421356",
  "trip_update" : {
    "trip" : {
      "trip_id" : "421356",
      "start_time" : "12:05:00",
      "start_date" : "20130926",
      "route_id" : "15"
    },
    "stop_time_update" : [{
       "stop_sequence" :70,
      "departure" : {
        "delay" : 240,
        "time" : 1380215057
      },
      "stop_id" : "6090"
    }, {
       "stop_sequence" :71,
      "departure" : {
        "delay" : 240,
        "time" : 1380215075
      },
      "stop_id" : "6095"
    }]
  }
}]

那么您将能够像这样遍历您的数据:

foreach($result[0]->trip_update->stop_time_update as $update)
{
     $time = $update->departure->time;
     ...
}

如果您无法更改数据结构,那么可能对您有所帮助的是一个 PULL 解析器——它不返回解析的数据结构,但允许您使用数据流——这样您就可以遍历每个节点。我设法找到的唯一一个是 PHP 的扩展:

https://github.com/shevron/ext-jsonreader

检查使用部分。

于 2013-09-26T19:53:52.130 回答
1

JSON响应无效,因为它包含重复的键,但JSON没有allow duplicate keys

您应该联系您尝试请求此响应的服务。

如果您有一个有效的JSON响应,那么您可以使用json_decode返回对象或数组的函数对其进行解码(取决于第二个参数);

您不能JSON parser为此使用 a ,因为由于相同的键,它总是会覆盖第一个元素。唯一合适的解决方案是要求创建该“JSON”的人修复他的代码以使用数组或具有唯一键的对象。

另一种选择是编写自己的解码器函数来解析它

于 2013-09-26T20:36:02.773 回答
1

嗨,也许你可以更改名称。

function next_update($coincidencias){
$replace=$coincidencias[0].$GLOBALS["json_stop_time_update"]++;
return $replace;
}
$result= preg_replace_callback("/stop_time_update/","next_update",$jsondata);
$result = json_decode($result);
于 2013-09-26T21:25:31.017 回答