ExtendScript 不包含具有关联解析方法的 JSON 对象,即JSON.parse()
and JSON.stringify()
。它也不提供任何其他用于解析 JSON 的内置功能。
解决方案:
考虑利用polyfill提供 JSON 功能,例如JSON-js由道格拉斯·克罗克福德创建。
您需要做什么:
-
下载名为的 JavaScript 文件json2.js从 Github 存储库并将其保存在与您的相同的位置/文件夹中.jsx
file.
Note您只需复制并粘贴即可json2.js 的原始版本从同一个 Github 存储库创建json2.js如果您愿意,可以手动归档。
-
然后在当前的顶部.jsx
您需要的文件#include
the json2.js
文件中添加以下代码行:
#include "json2.js";
这类似于您如何利用import声明在现代 JavaScript (ES6) 中包含一个模块。
A pathname到的位置json2.js
如果您决定将文件保存在与您的位置/文件夹不同的位置/文件夹中,则可以提供.jsx
file.
-
通过包括json2.js
在你的.jsx
文件,您现在将拥有有效的 JSON 方法;JSON.parse()
and JSON.stringify()
.
Example:
以下扩展脚本(.jsx
)是一个工作示例,它生成 JSON 以指示与当前 InDesign 文档关联的所有链接(.indd
).
示例.jsx
#include "json2.js";
$.level=0;
var doc = app.activeDocument;
/**
* Loads the AdobeXMPScript library.
* @returns {Boolean} True if the library loaded successfully, otherwise false.
*/
function loadXMPLibrary() {
if (!ExternalObject.AdobeXMPScript) {
try {
ExternalObject.AdobeXMPScript = new ExternalObject('lib:AdobeXMPScript');
} catch (e) {
alert('Failed loading AdobeXMPScript library\n' + e.message, 'Error', true);
return false;
}
}
return true;
}
/**
* Obtains the values f XMP properties for `DocumentID` and `instanceID` in
* each linked file associated with an InDesign document (.indd). A returns the
* information formatted as JSON,
* @param {Object} doc - A reference to the .indd to check.
* @returns {String} - The information formatted as JSON.
*/
function getLinksInfoAsJson(doc) {
var linksInfObj = {};
linksInfObj['indd-name'] = doc.name;
linksInfObj.location = doc.filePath.fsName;
linksInfObj.links = [];
for (var i = 0, len = doc.links.length; i < len; i++) {
var linkFilepath = File(doc.links[i].filePath).fsName;
var linkFileName = doc.links[i].name;
var xmpFile = new XMPFile(linkFilepath, XMPConst.FILE_INDESIGN, XMPConst.OPEN_FOR_READ);
var allXMP = xmpFile.getXMP();
// Retrieve values from external links XMP.
var documentID = allXMP.getProperty(XMPConst.NS_XMP_MM, 'DocumentID', XMPConst.STRING);
var instanceID = allXMP.getProperty(XMPConst.NS_XMP_MM, 'InstanceID', XMPConst.STRING);
// Ensure we produce valid JSON...
// - When `instanceID` or `documentID` values equal `undefined` change to `null`.
// - When `instanceID` or `documentID` exist ensure it's a String.
instanceID = instanceID ? String(instanceID) : null;
documentID = documentID ? String(documentID) : null;
linksInfObj.links.push({
'name': linkFileName,
'path': linkFilepath,
'docId': documentID,
'insId': instanceID
});
}
return JSON.stringify(linksInfObj, null, 2);
}
if (loadXMPLibrary()) {
var linksJson = getLinksInfoAsJson(doc);
$.writeln(linksJson);
}
Output:
运行上面的脚本会将类似于以下示例的 JSON 格式记录到您的控制台:
{
"indd-name": "foobar.indd",
"location": "/path/to/the/document",
"links":[
{
"name": "one.psd",
"path": "/path/to/the/document/links/one.psd",
"docId": "5E3AE91C0E2AD0A57A0318E078A125D6",
"insId": "xmp.iid:0480117407206811AFFD9EEDCD311C32"
},
{
"name": "two.jpg",
"path": "/path/to/the/document/links/two.jpg",
"docId": "EDC4CCF902ED087F654B6AB54C57A833",
"insId": "xmp.iid:FE7F117407206811A61394AAF02B0DD6"
},
{
"name": "three.png",
"path": "/path/to/the/document/links/three.png",
"docId": null,
"insId": null
}
]
}
旁注:对 JSON 进行建模:
您会注意到 JSON 输出(上面)的结构与您在给定示例中尝试构造它的方式不同。主要区别在于您使用链接文件名作为属性/键名称,例如以下示例:
有问题的 JSON 结构示例
{
"one.psd": {
"docId": "5E3AE91C0E2AD0A57A0318E078A125D6",
"insId": "xmp.iid:0480117407206811AFFD9EEDCD311C32"
},
"two.jpg": {
"docId": "EDC4CCF902ED087F654B6AB54C57A833",
"insId": "xmp.iid:FE7F117407206811A61394AAF02B0DD6"
}
...
}
像此示例一样生成 JSON 并不理想,因为如果您有两个具有相同名称的链接,则您只会报告其中之一。一个对象中不能有两个同名的属性/键。
Edit:
作为对OP评论的回应:
嗨,RobC,除了使用#include 'json2.js'
,还有其他方法可以将外部js文件包含在JSX文件中吗?
有以下几种替代方法:
-
你可以利用$.evalFile()。例如替换#include "json2.js";
与以下两行:
var json2 = File($.fileName).path + "/" + "json2.js";
$.evalFile(json2);
Note:此示例假设json2.js
与您位于同一文件夹中.jsx
-
或者,如果您想避免额外的存在json2.js
完整归档。你可以添加一个IIFE(立即调用函数表达式)位于您的顶部.jsx
文件。然后将内容复制粘贴到json2.js文件写入其中。例如:
(function () {
// <-- Paste the content of `json2.js` here.
})();
Note:如果代码大小是一个问题,那么考虑缩小化的内容json2.js
在将其粘贴到 IIFE 之前。