Edit:我找到了一个解决方案,使用htmlfile
COM 对象,它应该提供最快的性能(至少对于单次运行)并且不需要 Internet 连接。请参阅此答案中的最后一个解决方案。
因为您使用 [batch-file] 标签标记了这个问题,并且因为我发现这个挑战很有趣,所以我编写了一个混合批处理 + JScript 脚本来美化您的 JSON。自从JScript 5.7 本身不支持 JSON 对象,此脚本使用外部 json2.js,如果尚未下载,则通过 XHR 下载它。从那里,调用熟悉的 JavaScript 就很简单了JSON.stringify()
方法及其美化选项。
Syntax:
json_generator | batfile.bat
-or-
batfile.bat < jsonfile.json
用法示例:
beautify.bat < "C:\output\serviceName.json" > "C:\output\beautified.json"
这会导致以下内容保存为 beautified.json:
{
"status": "success",
"user": "name",
"regId": "14420",
"subscriber": [
{
"memberFor": "3 years",
"lastLogin": "2 days ago"
}
]
}
代码:
@if (@CodeSection == @Batch) @then
@echo off & setlocal
cscript /nologo /e:JScript "%~f0"
goto :EOF
@end // end Batch / begin JScript hybrid chimera
var xObj = WSH.CreateObject('Microsoft.XMLHTTP'),
fso = WSH.CreateObject('Scripting.FileSystemObject'),
temp = WSH.CreateObject('WScript.Shell').Environment('Process')('temp'),
j2lib = 'https://raw.githubusercontent.com/douglascrockford/JSON-js/master/json2.js',
json = WSH.StdIn.ReadAll();
if (fso.FileExists(temp + '\\json2.js')) {
j2lib = fso.OpenTextFile(temp + '\\json2.js', 1);
eval(j2lib.ReadAll());
j2lib.Close();
}
else {
with (xObj) {
open("GET", j2lib, true);
setRequestHeader('User-Agent', 'XMLHTTP/1.0');
send('');
}
while (xObj.readyState != 4) WSH.Sleep(50);
eval(xObj.responseText);
j2lib = fso.CreateTextFile(temp + '\\json2.js', true);
j2lib.Write(xObj.responseText);
j2lib.Close();
}
WSH.Echo(JSON.stringify(JSON.parse(json), null, '\t'));
这是另一个使用相同语法的解决方案,不需要下载 json2.js。它通过以不可见方式启动 Internet Explorer、调用 IE 的内置 JSON 方法,然后再次静默关闭 IE 来避免这种情况。这很可能比上面的方法慢,并且可能会根据机器安全策略被阻止;但它确实具有无需互联网连接即可工作的优点。
@if (@CodeSection == @Batch) @then
@echo off & setlocal
cscript /nologo /e:JScript "%~f0"
goto :EOF
@end // end Batch / begin JScript hybrid chimera
var IE = WSH.CreateObject('InternetExplorer.Application'),
json = WSH.StdIn.ReadAll();
IE.Visible = 0;
IE.Navigate('about:blank');
while (IE.Busy || IE.ReadyState != 4) WSH.Sleep(25);
var JSON = IE.document.parentWindow.JSON,
pretty = JSON.stringify(JSON.parse(json), null, "\t");
WSH.Echo(pretty);
IE.Quit();
try { while (IE && IE.Busy) WSH.Sleep(25); }
catch(e) {}
这是另一种解决方案,这次使用的是批处理/HTA 混合解决方案。有一个<meta>
标签强制 HTA 解释器兼容 IE9,从而包括
支持 JSON 方法。这比 IE 方法更快,但并不是完全不可见。 HTA 窗口在屏幕上闪烁一瞬间,然后自行关闭。
<!-- : batch portion
@echo off & setlocal
rem // The for /f loop forces mshta to communicate with stdout
rem // as a console script host. Without for /f, attempting
rem // to write to stdout results in an invalid handle error.
for /f "delims=" %%I in ('mshta.exe "%~f0"') do echo(%%I
goto :EOF
end batch / begin HTA : -->
<meta http-equiv="x-ua-compatible" content="IE=9" />
<script>
var fso = new ActiveXObject('Scripting.FileSystemObject'),
stdin = fso.GetStandardStream(0),
stdout = fso.GetStandardStream(1),
json = stdin.ReadAll(),
pretty = JSON.stringify(JSON.parse(json), null, '\t');
close(stdout.Write(pretty));
</script>
我认为最好的解决方案是使用文献记载不足 htmlfile
COM 对象。使用相同的技巧<meta>
标签以强制其与 IE9 兼容,如上面的 HTA 解决方案所示,htmlfile
COM 对象为 JSON 方法提供本机支持,无需下载库,也无需分叉额外的窗口帮助程序应用程序。它只是加载一个dll。
@if (@CodeSection == @Batch) @then
@echo off & setlocal
cscript /nologo /e:JScript "%~f0"
goto :EOF
@end // end batch / begin JScript hybrid chimera
var htmlfile = WSH.CreateObject('htmlfile'),
json = WSH.StdIn.ReadAll();
htmlfile.write('<meta http-equiv="x-ua-compatible" content="IE=9" />');
var JSON = htmlfile.parentWindow.JSON,
pretty = JSON.stringify(JSON.parse(json), null, '\t');
htmlfile.close(WSH.Echo(pretty));