我正在尝试解析从 REST Web 服务返回的一些 JSON。 get() 调用的返回是一个 TStringStream。我正在使用 dbxjson 来处理数据。为了使这里的演示更容易,我创建了一个测试项目,它可以在不调用 Web 服务的情况下重现错误(而是使用文本文件作为 Web 服务输出)。代码如下:
var SL : TStringStream;
LJsonObj : TJSONObject;
begin
SL := TStringStream.Create;
try
SL.LoadFromFile('output.txt');
LJsonObj := TJSONObject.ParseJSONValue(TEncoding.ASCII.GetBytes(SL.DataString), 0) as TJSONObject;
finally
SL.Free;
end;
end;
有时此 JSON 数据中的phone_numbers 数组为空。在来自 Web 服务调用的流对象中,它看起来像这样:
{
"Contact Information Service": {
"response": {
"phone_numbers": [
]
}
}
}
这会导致 ParseJSONValue 返回 nil 值。
但是,如果我在测试 txt 文件中将空的phone_numbers 数组更改为此:
{
"Contact Information Service": {
"response": {
"phone_numbers": []
}
}
}
它工作正常(即返回一个 TJSONObject)。区别在于空数组中的空格。由于某种原因,空数组中包含空格的第一个 JSON 响应会导致 ParseJSONValue 返回 nil。它工作正常,方括号之间没有空格。
我的 JSON 解析出了什么问题?在调用 ParseJSONValue 之前我需要进行某种预解析吗?
最佳答案
这个问题并不排除 Delphi JSON 实现 (DBXJSON),我使用了一些具有相同限制的 JSON PHP 解析器。
现在,由于 JSON 解析器(并且必须)忽略双引号字符串文字之外的所有空格,因此您可以安全地删除这些空格,因此可能的解决方法是 Minify 你的 Json 字符串,在解析它之前。
尝试此示例,它使用正则表达式从字符串中删除多余的空格。
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.RegularExpressions,
System.Classes,
System.SysUtils,
Data.DBXJSON;
const
JsonString=
'{'+
' "Contact Information Service": {'+
' "response": {'+
' "phone_numbers": [ ]'+
' }'+
' }'+
'}';
function JsonMinify(const S: string): string;
begin
Result:=TRegEx.Replace(S,'("(?:[^"\\]|\\.)*")|\s+', '$1');
end;
procedure TestJSon;
var
s : string;
SL : TStringStream;
LJsonObj : TJSONObject;
begin
SL := TStringStream.Create;
try
s:=JsonMinify(JsonString);
SL.WriteString(s);
LJsonObj := TJSONObject.ParseJSONValue(TEncoding.ASCII.GetBytes(SL.DataString), 0) as TJSONObject;
Writeln(LJsonObj.Size);
finally
SL.Free;
end;
end;
begin
try
TestJSon;
except
on E:Exception do
Writeln(E.Classname, ':', E.Message);
end;
Writeln('Press Enter to exit');
Readln;
end.
关于delphi - JSON 空数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12168982/