我正在使用Prolog中的简单Web服务,并希望使用格式化为JSON的数据来响应我的用户。一个很好的工具是reply_json_dict/1
,它接受一个字典,并使用格式正确的JSON主体在HTTP响应中对其进行转换。
我的麻烦在于构建响应字典本身似乎有点麻烦。例如,当我返回一些数据时,我有数据id但可能/可能没有数据属性(可能是未绑定的变量)。目前我做了以下事情:
OutDict0 = _{ id : DataId },
( nonvar(Props) -> OutDict1 = OutDict0.put(_{ attributes : Props }) ; OutDict1 = OutDict0 ),
reply_json_dict(OutDict1)
哪种方法正常,因此输出为{ "id" : "III" }
或{ "id" : "III", "attributes" : "AAA" }
,具体取决于Props
是否受约束,但是......我正在寻找一种更简单的方法。主要是因为如果我需要添加更多可选的键/值对,我最终会产生多种含义,如:
OutDict0 = _{ id : DataId },
( nonvar(Props) -> OutDict1 = OutDict0.put(_{ attributes : Props }) ; OutDict1 = OutDict0 ),
( nonvar(Time) -> OutDict2 = OutDict1.put(_{ time : Time }) ; OutDict2 = OutDict1 ),
( nonvar(UserName) -> OutDict3 = OutDict2.put(_{ userName : UserName }) ; OutDict3 = OutDict2 ),
reply_json_dict(OutDict3)
这似乎是错的。有更简单的方法吗?
干杯, 亚切克
答案 0 :(得分:3)
在这种情况下,我的建议是使用不同的谓词来发出JSON ,而不是乱用字典。
例如,考虑json_write/2
,它允许您在HTTP库所需的当前输出中发出JSON。
假设您对数据字段的表示是在整个HTTP库中用于选项处理的常用Name(Value)
表示法:
Fields0 = [attributes(Props),time(Time),userName(UserName)],
使用meta-predicate include/3
,您的整个示例变为:
main :- Fields0 = [id(DataId),attributes(Props),time(Time),userName(UserName)], include(ground, Fields0, Fields), json_write(current_output, json(Fields)).
您可以自己尝试一下,方法是在上面的代码段中为 singleton variables 中的各个元素插入合适的值。
例如,我们可以(任意)使用:
Fields0 = [id(i9),attributes(_),time('12:00'),userName(_)],
得到以下特性:
?- main. {"id":"i9", "time":"12:00"} true.
您只需要发出合适的内容类型标头,并且具有reply_json_dict/1
给您的相同输出。
答案 1 :(得分:2)
如果您使用列表来表示需要进入字典的所有值,则可以一步完成。
?- Props = [a,b,c], get_time(Time),
D0 = _{id:001},
include(ground, [props:Props,time:Time,user:UserName], Fs),
D = D0.put(Fs).
D0 = _17726{id:1},
Fs = [props:[a, b, c], time:1477557597.205908],
D = _17726{id:1, props:[a, b, c], time:1477557597.205908}.
这在使用include(ground)
的答案中借用了这个想法。
答案 2 :(得分:1)
非常感谢mat和Boris的建议!最后我结合了你的想法:
dict_filter_vars(DictIn, DictOut) :-
findall(Key=Value, (get_dict(Key, DictIn, Value), nonvar(Value)), Pairs),
dict_create(DictOut, _, Pairs).
然后我可以使用那么简单:
DictWithVars = _{ id : DataId, attributes : Props, time : Time, userName : UserName },
dict_filter_vars(DictWithVars, DictOut),
reply_json_dict(DictOut)