来自文本文件的多个 JSON 对象

Posted

技术标签:

【中文标题】来自文本文件的多个 JSON 对象【英文标题】:Multiple JSON objects from text file 【发布时间】:2014-12-16 13:14:27 【问题描述】:

您好,我正在尝试使用多个 json 对象,如下例所示。

[
  
    "DateandTime" : "1025",
    "LoggingLevel" : "ERROR",
    "Description" : "Test"
  
]
[
  
    "DateandTime" : "1025",
    "LoggingLevel" : "ERROR",
    "Description" : "Test"
  
]

这就是它从 ios 端创建的方式,因为我一次只创建一个对象,因为它用于报告日志系统,并且只需要在需要时传递消息。因此,Json 对象是在不同时间创建并附加到文件中的。

我知道一个有效的 Json 字符串如下所示。

[
  
    "DateandTime" : "1025",
    "LoggingLevel" : "ERROR",
    "Description" : "Test"
  ,

  
    "DateandTime" : "1025",
    "LoggingLevel" : "ERROR",
    "Description" : "Test"
  
]

但这不是我需要的。有没有办法使用两个单独的 Json 对象?

iOS

    NSString *DataString = [NSString stringWithFormat:@" \"DateandTime\":\"%@\", \"Description\":\"%@\", \"LoggingLevel\":\"%@\" ", @"1025", logString, [self getLogTypeName:(LOGS)level]];
    NSMutableArray *CurrentData = [NSJSONSerialization JSONObjectWithData:[DataString dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableContainers error:nil];
    NSMutableArray *ArrayOfData = [[NSMutableArray alloc] init];
    [ArrayOfData addObject:CurrentData];
    NSData *JsonObject = [NSJSONSerialization dataWithJSONObject:ArrayOfData options:0 error:nil];
    NSString *jsonString = [[NSString alloc] initWithData:JsonObject encoding:NSUTF8StringEncoding];

    post = [NSString stringWithFormat:@"Message=%@", jsonString];

php

$file = 'testingFile.txt';
// Open the file to get existing content
$current = file_get_contents($file);
if (isset($_POST['Message'])) 
// Append a new person to the file
$current .= $_POST['Message'] . PHP_EOL; 
// Write the contents back to the file
file_put_contents($file, $current);

 else 
    $Contents = file_get_contents($file);
    echo $Contents;

javascript

function GetLoggingData() 
  $.get("../ISOSEC/logging/TestPHP.php", function(data)
      $.each($.parseJSON(data), function(idx, obj) 
         console.log(obj.DateandTime);
         console.log(obj.LoggingLevel);
         console.log(obj.Description);
         AddLog(obj.DateandTime, obj.LoggingLevel, obj.Description);
      );

  );

如果文件中已经有一个 json 对象或者有其他解决方法,谁能告诉我如何将这些对象合并在一起?

谢谢。

【问题讨论】:

您必须为 JSON 解析器创建有效的 JSON 才能成功解析它。我相信你可以在解析器端做一些变通方法来让它工作。但是,您为什么不首先努力编写正确的 JSON? 就像@RonniEgeriis 说的那样,读取文件检查是否已经存在 json 字符串会容易得多,如果有添加新内容然后写入该文件,而不是找到解析它的方法. @RonniEgeriis 如果它只是我解释的一个对象,那么它是有效的 JSON。但是,我不会同时发送所有 JSON 数据,而是在不同时间发送,因为它们正在记录报告并只是附加到文本文件中。我更新了我的问题,问是否有人可以告诉我如何将两个对象附​​加在一起或以其他方式解决? @Chris 是的,但是当您在不遵守 JSON 语法的情况下开始附加数据时,它会变得无效。然后你创建自己的约定,这会让你很头疼。我想你使用NSJSONSerialization?在下面检查我的答案。 【参考方案1】:

正如我在评论中提到的,您最好使用有效的 JSON 生成文件,而不是尝试解析自己的 JSON 语法。

您可以通过解析现有 JSON 并根据需要附加对象来做到这一点。

概念(未测试)示例:

NSMutableArray *currentData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers errors:&errors];
[currentData addObject:newObject];
NSData *updatedJSONData = [NSJSONSerialization dataWithJSONObject:currentData options:0 errors:&errors];

更新

好的,就我看到您的问题而言,您有两个环境。你有客户端和服务器。我没有注意到的是各个日志消息是由您的 PHP 脚本处理的。

以下是我将在您的应用中执行的操作:

NSError *error;

// Simplify the generation of your dictionary
NSDictionary *logLine = @
    @"DateandTime": @"1024"
    @"Description": logString,
    @"LoggingLevel": [self getLogTypeName:(LOGS)level]
;

// Create JSON string from dictionary
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:logLine options:0 error:&error];
NSString *jsonStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

// Now post jsonStr as the HTTP body to your PHP script

这就是我在你的脚本中要做的:

<?php

$logFileName = 'testingFile.txt';

// Read your current log file contents
$currentLogJSON = file_get_contents($logFileName);

// Check the log for any contents
if (empty($currentLogJSON)) 
    $currentLog = [];
 else 
    $currentLog = json_decode($currentLogJSON);
    // Ensure that the contents of the log file is an array
    if (is_array($currentLog)) 
        $currentLog = [];
    


// Get the new log line from HTTP body
$newLogLineJSON = file_get_contents('php://input');
// Decode the log line which is passed as JSON string
$newLogLine = json_decode($newLogLine);
if (json_last_error() == JSON_ERROR_NONE) 
    // Append the log line to the current log
    $currentLog[] = $newLogLine;
    // Write the updated log contents to log file
    file_put_contents($logFileName, json_encode($currentLog));

【讨论】:

现在是这种格式-["DateandTime":"1025","LoggingLevel":"ERROR","Description":"Test"] ...但是我遇到了同样的问题,每次记录一些东西都会给我同样的问题。 ["DateandTime":"1025","LoggingLevel":"ERROR","Description":"Test"]["DateandTime":"1025","LoggingLevel":"MESSAGE","Description":"Another Time Run"] 你明白我的概念吗?您是否读取了日志文件的当前内容,将其解析为 NSObject,追加新的日志数据并将其再次序列化为 JSON 数据? @Chris 如果您在问题中提供您当前的代码,这将有助于更好地说明我的想法。 我已经用我当前的代码更新了我的问题。希望这足以让您更好地说明您的想法。 我已经测试过了,它在文本文件中给了我 [null]【参考方案2】:

如果你的文件总是看起来像第一个例子,你可以只做一个 preg_replace

这只是一个主题,它可能是一种不好的方式,但我认为它可以工作。

编辑

试试这个

$NewSingleJsonString = preg_replace("/.\].\[.\s+/s",',',$MultipleJsonString);

【讨论】:

preg_replace 似乎不起作用,它没有替代任何东西。

以上是关于来自文本文件的多个 JSON 对象的主要内容,如果未能解决你的问题,请参考以下文章

从文本文件加载 Json 对象 - 返回未捕获的语法错误:意外标记“[”

JSON下

循环批处理文件,用于将来自不同文件夹的多个文本文件合并到另一个不同文件夹中的一个文本文件

JSON的一点:

将 Json 对象导出到文本文件

如何从多个重复的 json 文件中删除一个文本块,其中文件之间有微小的变化?