我正在使用scriptcontrol / jscript在VBA中解析严重嵌套的JSON。 生成的JSON对象是超级嵌套的,并且具有重复的“无用”级别/层,称为“桶”。
有没有办法可以从我的json字符串或解析的json对象中集体删除它们?
想象一下这样的事情:
responses.0.buckets.0.aggregations.0.10.buckets.0.5.buckets.0.9.buckets.0.20.buckets.0.8.buckets.0.13.buckets.0.14.buckets.0.15.buckets.0.16.buckets.0.19 .buckets.0.18.buckets.0.21.doc_count_error_upper_bound
我只需要'doc_count_error_upper_bound'值,并且基本上可以在没有所有0且没有所有桶的情况下,使其更少嵌套:
responses.aggregations.10.5.9.20.8.13.14.15.16.19.18.21.doc_count_error_upper_bound
这仍然是非常重要的嵌套,但已经给我带来了很多麻烦。 我只是不知道如何使用VBA中的jscript / scriptcontrol(es3)。
源数据来自Kibana仪表板(http://demo.elastic.co/上的示例)
感谢您的帮助!
碧玉
更新 有关VBA代码的问题 - 我所拥有的VBA代码无关紧要,因为它是通过scriptcontrol将json字符串加载到对象中的标准方法。
我不使用EVAL,但出于示例目的,它将类似于以下内容:
Dim Scr as Object, Json as Object
Set Scr = CreateObject("Scriptcontrol")
Scr.Language = "Jscript"
Set Json = Scr.Eval("(" & WinHTTP.ResponseText & ")")
我无法共享JSON字符串的示例,因为它包含敏感数据。 但最终,这就是问题所在。 考虑示例https://adobe.github.io/Spry/data/json/donuts.js
在那里,“击球手”是“击球手”和不同身份证之间的关键。如果我想删除该密钥,但保留底层ID数据 - 我将如何通过在VBA中的scriptcontrol中工作的js脚本来实现?
更新
omegastripes的答案非常有效,但是,我没有意识到我想删除的一些键('buckets'和'0'等)在它们下面有键和值。
让我们以甜甜圈为例,只是改了一下 - 见这里: https://pastebin.com/WxYir7vK
现在我想删除'0','1','2'等密钥,而不会丢失底层子密钥。 但是,为了使omegastripes代码起作用,我必须从json的所有层/整个中删除键'sequence','variant','name'和'ppu'。
对于其中一个,我可以这样做,对于一个具有以下功能的层:
function unseat(obj, prop) { for(var k in obj[prop]) obj[k] = obj[prop][k]; delete obj[prop]; return obj; }
然后调用函数'unseat(JSONObj,“variant”)' - 这是有效的,但一次只能用于四个变量中的一个,而且仅用于一个层。 如何改变这一点,以便我可以一次性删除整个对象中的所有四个,以便之后我可以使用omegastripes代码来解包。
摘要
1)我拿这个json字符串:https://pastebin.com/WxYir7vK
2)将其解析为脚本控制到VBA中
3)遍历它并删除所有'sequence','variant','name'和'ppu'键/值对
4)通过omegastripes代码打开它。
步骤1/2和4都要照顾 - 但如何做3?
谢谢!
答案 0 :(得分:1)
使用ScriptControl解析JSON有以下缺点(详情请查看this answer):
无论如何,如果您确信在JScript环境中操作是唯一的方法,您可以使用以下函数解开对象和数组结构的过度嵌套:
function gParse(sample) {
return eval('(' + sample + ')');
};
function gUnwrap(sample) {
for (var key in sample) {
sample[key] = gUnwrap(sample[key]);
};
var count = 0;
for (var key in sample) {
count++;
if (count == 2) break;
};
if (count == 1) {
var type = gGetType(sample);
if (type == 'Array' || type == 'Object') {
var type = gGetType(sample[key]);
if (type == 'Array' || type == 'Object') {
return sample[key];
}
}
};
return sample;
};
function gGetType(sample) {
return {}.toString.call(sample).slice(8, -1);
};
可以在VBA中完成,如下所示:
Option Explicit
Sub Test()
Dim sJSON As String
Dim ParseJSON As Object
Dim UnwrapJSON As Object
Dim oJSON As Object
With CreateObject("MSXML2.XMLHTTP")
.Open "GET", "https://adobe.github.io/Spry/data/json/donuts.js", False
.send
sJSON = .responseText
End With
With CreateObject("htmlfile")
With .parentWindow
.execScript "function gParse(sample) {return eval('(' + sample + ')')};"
.execScript "function gUnwrap(sample) {for (var key in sample) {sample[key] = gUnwrap(sample[key]);}; var count = 0; for (var key in sample) {count++; if (count == 2) break;}; if (count == 1) {var type = gGetType(sample); if (type == 'Array' || type == 'Object') {var type = gGetType(sample[key]); if (type == 'Array' || type == 'Object') {return sample[key];}}}; return sample;};"
.execScript "function gGetType(sample) {return {}.toString.call(sample).slice(8, -1)};"
Set ParseJSON = .gParse
Set UnwrapJSON = .gUnwrap
End With
End With
Set oJSON = UnwrapJSON(ParseJSON(sJSON))
End Sub
locals窗口显示the sample you provided的JSON对象,如下所示:
解开JSON对象: