需要在 ExtendScript 中对对象进行 JSON 字符串化

2023-11-23

我正在使用 ExtendScript 处理 Indesign 文档链接的元数据信息。

我想使用将对象转换为字符串JSON.stringify但是当我使用它时,我收到错误消息:

can't execute script in target engine.

如果我删除linkObjStr = JSON.stringify(linksInfObj);从下面的代码来看,一切正常。

相当于什么JSON.stringify在ExtendScript中,或者是否有其他可能的显示linksInfObj以其正确的内容代替[object object]?

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);
    linksInfObj[linkFileName] = {'docId': documentID, 'insId': instanceID};
    linkObjStr = JSON.stringify(linksInfObj);

    alert('Object' + linksInfObj, true); // I am getting [Object Object] here
    alert('String' + linkObjStr, true);

}

ExtendScript 不包含具有关联解析方法的 JSON 对象,即JSON.parse() and JSON.stringify()。它也不提供任何其他用于解析 JSON 的内置功能。


解决方案:

考虑利用polyfill提供 JSON 功能,例如JSON-js由道格拉斯·克罗克福德创建。

您需要做什么:

  1. 下载名为的 JavaScript 文件json2.js从 Github 存储库并将其保存在与您的相同的位置/文件夹中.jsx file.

    Note您只需复制并粘贴即可json2.js 的原始版本从同一个 Github 存储库创建json2.js如果您愿意,可以手动归档。

  2. 然后在当前的顶部.jsx您需要的文件#include the json2.js文件中添加以下代码行:

     #include "json2.js";
    

    这类似于您如何利用import声明在现代 JavaScript (ES6) 中包含一个模块。

    A pathname到的位置json2.js如果您决定将文件保存在与您的位置/文件夹不同的位置/文件夹中,则可以提供.jsx file.

  3. 通过包括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文件中吗?

有以下几种替代方法:

  1. 你可以利用$.evalFile()。例如替换#include "json2.js";与以下两行:

     var json2 = File($.fileName).path + "/" + "json2.js";
     $.evalFile(json2);
    

    Note:此示例假设json2.js与您位于同一文件夹中.jsx

  2. 或者,如果您想避免额外的存在json2.js完整归档。你可以添加一个IIFE(立即调用函数表达式)位于您的顶部.jsx文件。然后将内容复制粘贴到json2.js文件写入其中。例如:

     (function () {
         // <-- Paste the content of `json2.js` here.
     })();
    

    Note:如果代码大小是一个问题,那么考虑缩小化的内容json2.js在将其粘贴到 IIFE 之前。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

需要在 ExtendScript 中对对象进行 JSON 字符串化 的相关文章

  • 使用 ScriptEngine 从 JavaScript 调用 Java 方法

    我正在使用 ScriptEngine 运行 JavaScript 我希望 JavaScript 脚本能够调用 myFunction 其中 myFunction 是我的给定类中的一个方法 我知道可以将 importPackage 用于标准 J
  • 使用 HTML5 FileSystem API 将文件写入桌面

    我正在玩一下文件系统API http www html5rocks com en tutorials file filesystem 我发现了很多生成下载链接并让用户以 浏览器方式 下载文件的示例 我想知道两件事 有没有办法将fiddle中
  • 从数组数组中获取唯一值[重复]

    这个问题在这里已经有答案了 我有以下数组 let arr email protected cdn cgi l email protection email protected cdn cgi l email protection email
  • Yeoman-Angular 生成的应用程序中缺少 Angular 脚本

    我已经使用 Yeoman Angular Generator 生成了一个应用程序 但项目中缺少 angular js 和其他 Angular 文件 我可以在 Bower json 文件中看到这些依赖项 如下所示 name mi portfo
  • Jqplot 中两个系列数据的不同颜色条

    我想知道如何在 Jqplot 中为两个系列制作不同的颜色条 如果我只有一个系列数据 它的工作原理如下图所示 红色和绿色基于其值 但是 如果我有两个系列数据 我无法为每个系列数据配置两个系列颜色 目前我只能做这个图 我希望两个系列图可以根据其
  • Object.assign() - 奇怪的行为需要解释

    我有这个代码 function margeOptions options passedOptions options Object assign options passedOptions let passedOpts a true let
  • 使用 JavaScript 填写 PDF 表单

    这就是我所拥有的 用户填写很长的 html 表单 用户获取下载不同 pdf 的链接 这是可填写的表格 链接是使用 javascript 生成的 用户单击链接 生成 url 使用用户之前提交的数据 在表单中处理数据并完成字段 这是在表单内使用
  • 使用 word_number 值对 javascript 数组进行排序

    如何对数组进行排序 var arr new Array word 12 word 59 word 17 这样我得到 word 12 word 17 word 59 Thanks 您需要编写一个排序方法 您可以编写任何您喜欢的方法 该方法在
  • TypeScript 中类和命名空间的区别

    到底有什么区别classes and namespaces在打字稿中 我知道 如果您创建一个带有静态方法的类 您可以在不实例化该类的情况下访问它们 这正是我猜想的命名空间的要点之一 我还知道你可以创建多个同名的命名空间 并且它们的方法在编译
  • Ember.js 数组作为模型的属性

    干杯 我有一些模型 它的一个属性是一个数组 但由于某些原因 我在服务器上使用 mongoDB 并且它是嵌入式模型和 ember data 的问题 我不能做这样的事情 App Foo DS Model extend numbers DS ha
  • 使用 getElementById 在 javascript 中使用正则表达式进行 Html 表单验证?

    我想使用正则表达式验证 html 表单的示例模式 AAA 111 2222 aa 1234 目前 我的代码要么为所有输入返回 正确 要么为所有输入返回 不正确 并且我无法弄清楚我的问题出在哪里 var x document getEleme
  • contenteditable 在 safari 中不起作用,但在 chrome 中起作用

    我有一个奇怪的问题 这在 chrome 中按预期工作 但在 safari 中它只会发光 但不会对按键输入做出反应 这是触发文本版本的方法 var namebloc event currentTarget find column filena
  • Angular UI.Bootstrap 单选按钮在 ng-repeat 中表现得很奇怪[重复]

    这个问题在这里已经有答案了 我在 Angular 的 ui bootstrap 中动态生成无线电模型的选项时遇到问题 我想我可以简单地对数组进行 ng repeat 使用 btn radio 属性的内容 如下所示 in the contro
  • 如何防止在达到一定字符数后向文本区域输入内容?

    使用下面的代码 任何超过指定最大值的输入都将被删除 但这会产生一种效果 即键入字符后立即将其删除 我宁愿简单地阻止输入字符
  • JQuery _renderItem 没有被调用

    我正在尝试使用 renderItem 函数创建自定义 ui menu item 元素 但经过可能尝试后 我什至无法调用该函数 自动完成功能正在工作 但就像 renderItem 函数不存在一样 这是我的脚本部分
  • 如何让无限滚动发挥作用?

    我正在尝试让这个无限加载脚本在我的项目中工作 这是我的 HTML div div div class pagina div div class pagina div div class pagina div div class pagina
  • 使用重复模式捕获正则表达式

    我试图捕获字符串的所有部分 但我似乎无法正确处理 该字符串具有以下结构 1 22 33 中间有运算符的数字 可以有任意数量的术语 我想要的是 1 22 33 1 22 33 但我得到 1 22 33 22 33 我尝试过各种正则表达式 这是
  • 谷歌地图绘制两点之间的路线

    我编写了这段无辜的 JavaScript 代码 它允许用户创建两个标记并绘制它们之间的路线 它不起作用 相反 它给出了一个奇怪的错误 Uncaught TypeError Cannot read property ya of undefin
  • ES6解构对象赋值函数参数默认值

    您好 我正在查看在传递函数参数时使用对象解构的示例对象解构演示 https developer mozilla org en US docs Web JavaScript Reference Operators Destructuring
  • 通过jquery ajax()和serialize()提交html表单

    我想通过 jquery ajax 提交此表单 这是我所做的 但它不起作用 即表单正在提交并刷新页面 但我没有看到响应 即在同一页面上打印数组 HTML

随机推荐

  • 为什么这不起作用?选择中的动态

    好的 我这样做 Select Range 1 20 gt Dynamic q 然后我创建滑块 Slider Dynamic q 1 20 它总是返回一个空集 为什么 Update这样做的目的是当我移动滑块时让设置发生变化 关键是 请记住 D
  • 我可以使用什么正则表达式来查找逗号分隔列表中的 Nᵗʰ 条目?

    I need a regular expression that can be used to find the Nth entry in a comma separated list 例如 假设此列表如下所示 abc def 4322 e
  • Google Chrome 在崩溃后恢复会话 cookie,如何避免?

    在 Google Chrome 上 我在 Windows 8 1 上的版本 35 上看到了这个 到目前为止我没有尝试其他版本 当浏览器崩溃时 或者您只需拔掉电源线 您将被要求恢复上一个会话当你再次打开它时 好的feature but 它也会
  • 如何解决 shell 脚本中的此错误:“read: Illegal option -t”?

    bin bash echo n Hurry up and type something gt if read t 10 response then echo Greate you made it in time else echo sorr
  • win7无法安装Cython

    所以我尝试在 ta lib 上使用 Cython 并且使用 mrjbq7 提供的包装器 非常感谢 所以我尝试在我的计算机上安装 Cython 0 19 1 然后执行python setup py install在 ta lib master
  • 从一个 NSMutableArray 中删除包含在另一个数组中的元素

    我有两个数组 A 和 B 如果 B 中存在这些元素 如何从 A 中删除这些元素 例如数组A 1 2 3 4 5 数组B 1 3 我想从数组 A 中删除 1 和 3 这样操作后数组 A 只包含 2 4 5 除了循环之外 还有其他更有效的方法吗
  • 操作邮件程序 SMTP 谷歌应用程序

    我尝试将 actionmailer 配置为通过 google apps 使用 smtp 发送 config action mailer delivery method smtp config action mailer smtp setti
  • 将字节数组中的 ASCII 转换为字符串

    我在 C 中的字符串转换似乎遇到了问题 我的应用程序收到了一个由 ASCII 字符串 每个字符一个字节 组成的字节数组 不幸的是 它的第一个位置也有一个 0 那么如何将这个字节数组转换为 C 字符串呢 以下是我尝试转换的数据示例 byte
  • 在 Excel VBA 工作簿的立即窗口中执行多行

    我是否只能在 Excel VBA 立即窗口中执行 1 个命令 有没有办法执行多个语句 使用冒号 将多个语句连接在一起的键 前任 MsgBox msgBox1 MsgBox msgBox2 将显示两个警报消息框
  • 使用 Java 连接到 Microsoft Dynamics CRM 本地 Web 服务?

    是否有任何在线资源显示使用 Java 编写的客户端访问 Microsoft CRM 本地 Web 服务的基本步骤 我应该使用哪个 Web 服务工具包 我尝试使用 JAXB 但 WSDL 元素命名存在冲突 需要类自定义 如果我找到正确的绑定修
  • 在C中访问另一个程序的变量

    在Python中 您可以使用id函数来了解变量的内存位置 因此 X Hello world print id X Output is equal to 139806692112112 0x7F27483876F0 我尝试使用 C 中的指针访
  • HashMap 的构建器

    Guava 为我们提供了很棒的 Java 类型工厂方法 例如Maps newHashMap 但是还有 java 地图构建器吗 HashMap
  • 确定弯曲、拉长区域的中线

    想象一下我有一个热狗的二维图像 我可以在热狗两端之间画一条直线 将此称为中线 它的属性之一是 2D 热狗围绕它具有最低惯性矩的轴 现在 如果我将热狗弯曲成弧形 这条中线也会扭曲 给定一张弯曲热狗的图片 我如何确定这条弯曲的中线 该算法应该容
  • 当在 apache httpd 中完成 URL 重写时,POST 请求将转换为 GET

    我有一个 apache Web 服务器 充当内部应用程序服务器的反向代理 我使用 ProxyPass 和 ProxyPassReverse 来实现这一点 我有多个上下文根映射到不同的应用程序 我正在尝试从一个上下文的域名中删除上下文根 以便
  • C# 反序列化 Json 未知键

    我有这个 JSON 我必须反序列化它 homepage http files minecraftforge net maven net minecraftforge forge promos 1 10 latest 12 18 0 2000
  • 如何从 ID3D11Texture2D 访问像素数据?

    我正在使用 Windows 桌面复制 API 来制定自己的镜像协议 我有这段代码 Get new frame HRESULT hr m DeskDupl gt AcquireNextFrame 500 FrameInfo DesktopRe
  • Python - 使用“导入信号”处理 CTRL+D

    I can currently handle CTRL C via def hand inter signum frame print hey nice job signal signal signal SIGINT hand inter
  • MAUI blazor 发生了未处理的错误

    如果程序中有错误 我会收到 发生未处理的错误 通过 Blazor Web 程序集 我可以在浏览器中打开开发人员工具来获取所发生情况的详细信息 这在 Blazor MAUI 中是不可能的 那么如何获取 Blazor MAUI 中的错误详细信息
  • 按下 JFrame 中的按钮后打开 JPanel [重复]

    这个问题在这里已经有答案了 我知道有人问过这个问题 但我未能找到解决方案 我创建了一个JFrame对于登录 我想在按下 Cont Nou 按钮后为新帐户打开一个带有 jpanel 的新窗口 但不知道如何使初始框架消失并显示带有 jpanel
  • 需要在 ExtendScript 中对对象进行 JSON 字符串化

    我正在使用 ExtendScript 处理 Indesign 文档链接的元数据信息 我想使用将对象转换为字符串JSON stringify但是当我使用它时 我收到错误消息 can t execute script in target eng