我使用Inno JSON Config(类似于Pascal Script fails to retrieve wide string from a custom DLL)来读取一个名为items.json的简单JSON文件:

{
    "Item_0":{
            "Key_1": "String 1",
            "Key_2": "1",
            "Key_3": "True"
    },
    "Item_1":{
            "Key_1": "String 2",
            "Key_2": "2",
            "Key_3": "False"
    }
}

以下是我的代码:

[Files]
Source: "JSONConfig.dll";            DestDir: "{tmp}\src";          Flags: dontcopy;       
Source: "json_lists\*";              DestDir: "{tmp}\json_lists";   Flags: dontcopy;

[Code]
var
  ItemList: array of WideString;

function JSONQueryString(FileName, Section, Key, Default: WideString;
  var Value: WideString; var ValueLength: Integer): Boolean;
  external 'JSONQueryString@files:jsonconfig.dll stdcall';

procedure AppendItem(var ItemArray: array of WideString; Item: WideString);
begin
  SetLength(ItemArray, GetArrayLength(ItemArray) + 1);
  ItemArray[GetArrayLength(ItemArray) - 1] := Item;
end;
  
function ParseJson(Filename: WideString; Item: String; Key: String; var ItemArray: array of WideString): Boolean;
var
  StrValue: WideString;
  StrLength: Integer;
  ItemNumber: Integer;
  Path: WideString;
begin  
  SetLength(StrValue, 32);
  StrLength := Length(StrValue);

  result := False;
  Path := ExpandConstant('{tmp}'+ '\json_lists\' + Filename);
  ItemNumber := 0;
  while JSONQueryString(Path, ExpandConstant(Item + '_' + IntToStr(ItemNumber)), Key, 'Default', StrValue, StrLength) do
  begin
    ItemNumber := ItemNumber + 1;
    AppendItem(ItemArray, StrValue);
    result := True;
  end;
end;

function NextButtonClick(CurPageID: Integer): Boolean;
var
  I: Integer;
  PathForNextFile: WideString;
begin
  if CurPageID = wpWelcome then
  begin
    if GetArrayLength(ItemList) = 0 then begin
      ExtractTemporaryFiles('{tmp}\json_lists\*');
      if ParseJson('items.json','Item', 'Key_1', ItemList) then begin
        for I := 0 to GetArrayLength(ItemList) - 1 do begin
          PathForNextFile := ItemList[I] + '.json';
          Log(PathForNextFile);     //**
        end;
      end else begin
        Log('Error while parsing')
      end;
    end;
  end;
  result := True;
end;

我在代码(第Log(PathForNextFile);行)中有两个值为//**的问题:

  • 日志(log)只提示‘字符串’,不带以下数字(通常为0或1);
  • 日志(log)不会提示后缀‘.json’.这很有问题,因为我需要后缀为‘.json’的变量PathForNextFile来解析另一个文件.

我不知道为什么会发生这种情况,欢迎任何帮助!

理想情况下,我只想处理String,而不是WideString,那么我是否应该编写一个PowerShell脚本,在Inno Setup中调用该脚本时,如果可能的话,将返回正确的信息String? 我试着使用Koldev的JsonParser Library,但我不知道它是如何工作的,即使是How to parse a JSON string in Inno Setup?,所以仍然欢迎任何帮助!

推荐答案

即使是来自Inno Setup: Working with JSON的原始代码也会返回截断的值.comment there by @yuval from 2015(!)说:

此外,JSONQuery字符串永远不会检索最后一个字符


我建议你用JsonParser library美元.

以下是使用JsonParser库(以及我的How to parse a JSON string in Inno Setup?中的便利函数)实现的代码的类似功能:

function ParseJsonFile(
  Filename: string; Item: string; Key: string; var ItemArray: array of string):
  Boolean;
var
  JsonLines: TStringList;
  JsonParser: TJsonParser;
  ItemNumber: Integer;
  JsonRoot, ItemObject: TJsonObject;
  StrValue: TJsonString; // = WideString = string
  ItemKey: string;
begin
  JsonLines := TStringList.Create;
  JsonLines.LoadFromFile(Filename);

  Result := False;
  if ParseJsonAndLogErrors(JsonParser, JsonLines.Text) then
  begin
    JsonRoot := GetJsonRoot(JsonParser.Output);
    ItemNumber := 0;
    while True do
    begin
      ItemKey := Format('%s_%d', [Item, ItemNumber]);
      if FindJsonObject(JsonParser.Output, JsonRoot, ItemKey, ItemObject) and
         FindJsonString(JsonParser.Output, ItemObject, Key, StrValue) then
      begin
        Inc(ItemNumber);
        SetLength(ItemArray, GetArrayLength(ItemArray) + 1);
        ItemArray[GetArrayLength(ItemArray) - 1] := StrValue;
        Result := True;
      end
        else Break;
    end;
  end;

  ClearJsonParser(JsonParser);
end;

Json相关问答推荐

Azure Data Factory JSON输出格式问题

使用快速json库编写json可以消除所有缩进

JOLT转换以根据条件删除json对象

使用 jq 重新格式化 JSON 输出

如何将一个对象添加到多个对象中 JOLT

在Databricks中如何将JSON文件作为字典读取

使用 map_values Select 包含空格的字符串未按预期工作

使用 JQ 获取 JSON 中的替代元素(输出:JSON 对象)

将 JSON 文件放在哪里以在 Angular 8 应用程序中加载静态 JSON 数据?

通过一个序列化器更新多个模型数据

Powershell 无法从名为 count 的键中获取价值

使用 Ansible 解析来自 Juniper 交换机的 JSON 输出

PowerShell - 如何迭代 PSCustomObject 嵌套对象?

hook到 Decodable.init() 以获得未指定的键?

应该使用什么标头将 GZIP 压缩 JSON 从 Android 客户端发送到服务器?

JSON Schema:验证数字或空值

在 React 中访问子级的父级状态

将循环 struct 转换为 JSON - 有什么方法可以找到它抱怨的字段?

如何从 JSON 响应中提取单个值?

是否有一个 PHP 函数只在双引号而不是单引号中添加斜杠