动态数据对象

对象是一种可以在单个变量中保存多个值的数据结构。当您具有全部都与脚本中的“事物”相关的值的集合时,它们非常有用。例如,您可能有一组与联系人相关的数据,例如姓名、电话号码和电子邮件地址。您可以将所有这些值存储在一个对象中。这样做的好处是可以减少脚本中使用的变量数量。

Studio 支持 DynamicData 类型的对象。此类型可以处理没有静态格式或类型的数据,例如 XML 或 JSON。

您可以通过 Snippet 代码中声明或解析 JSON 或 XML 来创建动态数据对象。它们也是根据 API 调用的响应和某些框架操作创建的。

您可以在能够使用标准变量的任何 Studio 操作中使用动态数据对象。动态数据对象可用于保存数据,就像标准变量一样。它们还有其他用途。例如,您可以使用它们来:

脚本中动态数据变量和对象的数量会影响跟踪。对于包含大量动态变量的脚本,您可能会看到性能问题。包含的数据越多,处理每个操作所需的时间就越长。

有关动态数据对象的关键事实

  • 动态数据对象保存的值称为成员。
  • 每个成员都由一个名称来加以标识。例如,在 beowulfCharacteristics.occupation 中,beowulf 是对象,occupation 是其成员之一的名称。
  • 对象成员的类型是在运行时确定的。编译器保存有关属性的信息。在运行时检查这些信息并根据它们采取行动。因此,编译器不会捕获动态数据对象的错误。而错误会导致运行时异常。
  • 动态数据对象可以具有动态创建的成员。在脚本中声明动态数据对象后,您可以在后续行中为该对象的成员分配值。您甚至可以为其他代码片段中的成员分配值。如果这些成员不存在,则会自动创建它们并为其分配指定的值。
  • 动态数据对象可以存储多种类型的数据。标准 Snippet 变量为隐式类型,表示在 Studio 编译器编译代码时就已确定该类型。动态数据对象的类型为 DynamicData。对象的成员为隐式类型。
  • 引用动态数据对象的成员时,区分大小写很重要。例如,如果试图使用 ASSIGN fileContent = "{beowulfcharacteristics.Files.file}" 解析 beowulfCharacteristics.files.file 的值,则不会返回任何结果。这是因为动态对象成员 Files.filefiles.file 不同。
  • 动态数据对象的所有成员都有一个特殊属性 $value。您无法为此属性指定值。它允许您与成员一起执行某些以其他方式无法执行的操作。
  • 动态数据对象及其成员必须小于 32 KB。将对象转换为 JSON 或 XML 时,生成的内容必须小于 32 KB。如果转换后的对象的内容超出该限制,则会被截断。

试试看

下载对象示例脚本并将其导入 Studio。此帮助页面中的一些示例可在示例脚本的 Snippet 操作中使用。您可以打开 Snippet Editor 窗口并运行调试器,了解每个示例是如何工作的。

对象成员

动态数据对象以键/值对的形式保存它们的属性,也称为成员。键是成员的名称,就像对象内变量的名称。在以下示例中,键为 nameoccupationfoe。每个键都有一个与之关联的值,该值用双引号括在等号右侧。

DYNAMIC beowulfCharacteristics
beowulfCharacteristics.name = "Beowulf"
beowulfCharacteristics.occupation= "Hero" 
beowulfCharacteristics.foe = "Grendel" 

动态数据对象允许您减少脚本中使用的变量数量。前面的示例展示了如何使用单个对象来保存三个值,而不是创建三个唯一变量。

动态数据对象的成员可以有自己的成员集。这些子成员遵循与一级成员相同的规则。例如:

DYNAMIC beowulfFoes
beowulfFoes.foe1.name = "Grendel"
beowulfFoes.foe1.type = "monster"
beowulfFoes.foe1.status = "defeated"
beowulfFoes.foe2.name = "Grendel's mother"
beowulfFoes.foe2.type = "monster"
beowulfFoes.foe2.status = "defeated" 

动态数据对象语法摘要

本节总结了与在 Studio 脚本中使用动态数据对象相关的语法。您可以在本页的其他部分了解更多信息。

使用以下语法声明动态数据对象:

DYNAMIC <objectName> [FROM 'string' | var]

<objectName> 必须遵循与 Studio 中的标准变量相同的命名准则。对象名称区分大小写。

FROM 子句是可选的。您可以使用它从字符串'string'或包含 JSON 或 XML 字符串的脚本变量var的内容创建对象。如果您使用 'string',它必须完全在一行上并用单引号引起来。

使用以下语法将成员添加到对象:

<objectName>.<memberName> = "value"

成员名称区分大小写。您不必使用关键字向对象添加成员,但如果需要,可以使用 ASSIGN

使用以下语法在动态数据对象中创建数组

DYNAMIC <object>

ASSIGN <object>.<member>[<index>].<sub-member>= "value"

声明动态数据对象

要声明动态数据对象,请在代码中变量名称之前使用关键字 DYNAMIC,然后向其添加属性。例如:

DYNAMIC beowulfCharacteristics
ASSIGN beowulfCharacteristics.name = "Beowulf"
ASSIGN beowulfCharacteristics.occupation= "Hero" 
ASSIGN beowulfCharacteristics.foe = "Grendel"

您不需要关键字来声明对象成员。如果您愿意,可以使用 ASSIGN。如果成员尚不存在,则引用成员会动态创建该成员。

引用动态数据对象成员

当需要使用动态数据对象包含的值时,必须引用保存该值的成员。使用以下格式:

<dynamicObjectName>.<memberName>

您可以像使用标准变量一样使用它。您可以在接受变量替换的任何 Studio 操作属性以及片段中引用动态数据对象。

例如,要引用以下对象的名称成员,您可以使用 beowulfCharacteristics.name

DYNAMIC beowulfCharacteristics
beowulfCharacteristics.name = "Beowulf"
beowulfCharacteristics.occupation= "Hero" 
beowulfCharacteristics.foe = "Grendel" 

特殊对象属性 $value

动态数据对象有一个特殊属性 $value。此属性允许您以其他方式不可行的方式处理对象及其值。您可以使用它来:

  • 将函数与对象的成员一起使用。例如:beowulfCharacteristics.name.first.$value.length()。您可以在下一节中了解有关将函数与对象一起运行的更多信息。
  • 使用 $value 属性将值从动态数据对象属性复制到常规变量:x = name.first.$value

您无法为 $value 赋值。它是只读的。

函数与对象

函数是可以在脚本中调用和运行的区块。函数允许您与变量或对象中的值进行交互。函数可以修改值或告诉您有关它们的信息。例如,有些函数可以转换变量或对象成员值的大小写。还有其他函数可以计算数组中元素的数量或告诉您某个值是否为数字。

有许多函数可供您在脚本中与动态数据对象一起使用。您只能在对象成员上运行函数,而不能在对象本身上运行函数。

要将函数与对象一起使用,请使用特殊的对象属性 $value。此属性是只读的,不会导致在对象中创建 $value 属性。它防止函数的名称成为对象的属性。它返回与其一起使用的对象成员的文字字符串值。

使用以下语法在对象成员上运行函数:obj.member.$value.function()

例如,要在 name.first 上运行 length() 函数,您可以使用:

ASSIGN length = name.first.$value.length()

将对象值复制到另一个对象或变量

如果您需要数据的两个版本,您可以为对象保存的数据创建副本。这使您可以更改一个而不影响另一个。为此,请使用内置的 copy() 函数并遵循以下语法:

DYNAMIC <object1>

DYNAMIC <object2>

<object1> = copy(<object2>)

您将数据复制到的变量可以是动态对象或标准 Studio 变量。如果它是标准变量,它会自动转换为动态对象。

copy() 函数比赋值引用占用更多的系统资源。它通过将对象转换为文本表示,然后再转换回对象,从而执行深度复制。如果处理的对象包含大量数据,这一过程可能会影响脚本的运行。

您可以将值从动态对象的子成员复制到另一个动态对象的子成员中。copy() 函数不适用于子成员,因此您需要将变量设置为彼此相等:

DYNAMIC currentContact
currentContact.who = beowulfCharacteristics.name

您可以将值从动态对象的子成员复制到标准变量中。这会自动导致变量被转换为动态对象。为了防止这种情况,您要复制的动态对象和子成员的名称必须用双引号和大括号括起来。这可以防止变量被转换为动态对象。例如:

ASSIGN currentContact = "{beowulfCharacteristics.foe}"

格式化对象名称的另一种方法是添加 $value 属性:

ASSIGN currentContact = beowulfCharacteristics.foe.$value

将对对象值的引用分配给另一个对象或变量

您可以将对动态数据对象的引用分配给另一个动态对象。例如:

DYNAMIC beowulfCharacteristics
ASSIGN beowulfCharacteristics.name = "Beowulf"
ASSIGN beowulfCharacteristics.occupation= "Hero" 
ASSIGN beowulfCharacteristics.foe = "Grendel"

DYNAMIC currentContact

ASSIGN currentContact = beowulfCharacteristics

经过上述赋值后,currentContactbeowulfCharacterics 都引用相同的物理数据。如果更改任一动态对象中子成员的值,则该值在另一个对象中也会更改。例如,如果将 currentContact.name 更改为 Beowulf Herot,则 beowulfCharacteristics.name 的值会自动更新为 Beowulf Herot。同样,如果将 beowulfCharacteristics.name 的值更改为 Sparky,则 currentContact.name 的值会自动更新为 Sparky

您不能将引用分配给单个子成员。您可以将子成员的值从一个动态对象复制到另一个动态对象。这会重复该值。如果更改一个值,它不会自动更改另一个值。

从 JSON 或 XML 创建动态数据对象

您可以使用动态数据对象来解析 JSON 或 XML。

定义动态数据对象,并使用 FROM 命令指定 JSON 或 XML 数据,语法如下:

DYNAMIC <objectName> [FROM 'string' | var]

您可以指定包含 JSON 或 XML 数据的 'string'。您还可以指定包含 JSON 字符串或 XML 数据的脚本变量 var 的名称。如果您使用 'string',它必须完全在一行上。如果 'string' 断到第二行,则会导致错误。

例如:

DYNAMIC beowulfWeapons FROM '{ "key1": "Hrothgars gift", "key2": "Hrunting", "key3": "Naegling"}'

其结果是:

beowulfWeapons.key1 = "Hrothgars gift"  
beowulfWeapons.key2 = "Hrunting" 
beowulfWeapons.key3 = "Naegling"

如果上例中使用的 JSON 键值对包含在名为 famousSwords 的变量中,您可以像这样创建动态数据对象:

DYNAMIC epicMonsterDoom FROM famousSwords

两种创建对象的方法的结果是相同的。

Studio 中,__type(带有两个下划线字符)在解析 JSON 时使用。它不能用作动态数据变量的键名,因为它们可以解析 JSON。 如果将其用作动态数据变量中的键名,则在保存该脚本或该脚本执行操作时会导致错误

将 JSON 字符串分配给变量

使用 JSON 字符串时的另一个选择是将它们分配给变量,而不是动态对象。这不是使用 JSON 字符串的首选方法。它无法让您像在动态对象中使用 JSON 那样灵活地管理和使用代码。然而,有时可能是必要的。

在将 JSON 字符串分配给变量之前,必须将大括号 ({) 和双引号 (") 字符替换为转义字符。您可以使用文本编辑器手动替换这些字符,也可以使用 replace() 函数在脚本中执行此操作。在变量赋值中,JSON 字符串必须以美元符号 ( $ ) 为前缀,如下例所示。美元符号指示包含转义字符的值。

ASSIGN customPayloadFromBotJson = $"\{\"prompts\": [\{\"mediaSpecificObject\": \{\"dfoMessage\": \{\"messageContent\": \{\"type\": \"PLUGIN\", \"payload\": \{\"elements\": [\{\"id\": \"bf2521f4-5e85-413f-b6ed-815d1c3905f0\", \"type\": \"FILE\", \"filename\": \"photo.jpg\", \"url\": \"https://www.nice.com/-/media/niceincontact/layout/nice-logo-web-header/nice-web-logo.ashx\", \"mimeType\": \"image/jpeg\"}]}}}}}]}"
		

从 REST 响应创建动态数据对象

动态数据对象是从 REST API 调用的响应自动创建的。这些响应可以是 JSON 或 XML。Studio 将其转换为脚本中的动态数据对象。例如:

ASSIGN GetRequest = "<API Endpoint>"
ASSIGN DynamicReturn = Proxy.MakeRestRequest(GetRequest,"",0,"GET")
ASSIGN fileContent = "{DynamicReturn.files.file}"

在此示例中,MakeRestRequest() 函数会返回动态数据对象,DynamicReturn。您无需将 DYNAMIC 关键字与此变量一起使用,因为脚本会自动使其成为动态数据对象。

要解析包含 REST 响应的动态数据对象,请使用 ASSIGN fileContent = "{DynamicReturn.files.file}"。这会将提取的值 ({DynamicReturn.files.file}) 分配给 fileContent 变量。您还可以使用ASSIGN fileContent = DynamicReturn.files.file.$value来解析响应。

为 REST API 调用准备有效负载数据

您可以为 REST API 调用准备有效负载数据,并使用 asjson() 函数将其作为 JSON 发送。此任务的首选方法是使用 REST API 操作。但是,您也可以在代码片段中完成它。例如:

DYNAMIC tokenInput
ASSIGN tokenInput.grant_type = "password"
ASSIGN tokenInput.username = "Grendel.Cainson"
ASSIGN tokenInput.password = "MadeUpPassword"
	<additional tokenInput properties> 
ASSIGN tokenJsonInput = "{tokenInput.asjson()}"
ASSIGN proxy = GETRESTProxy()
<ASSIGN additional variables as needed>
ASSIGN tokenResponse = proxy.MakeRestRequest(TokenRequestURL,TokenJsonInput, 0, "POST")

在此示例中,TokenInput 声明为具有 grant_typeusernamepassword 三个成员的动态变量。TokenJsonInput 使用 asjson() 函数声明以字符串形式保存 TokenInput。在示例的最后一行中,声明了变量 TokenResponse 来保存 REST 请求,然后可以在脚本代码中使用该变量来发送请求。

将动态数据对象转换为 JSON 或 XML

您可以将动态对象的内容转换为 JSON 或 XML 字符串。这会序列化对象中的数据并将其转换为可以通过 Internet 传输的格式。

为此,请对要转换的对象使用 asjson()asxml() 函数。在 Studio 中,您可以在两个位置之一执行此操作:在 Snippet 操作中或在需要从对象转换数据的操作属性中。

两种方法的工作原理相同。不过,在 Snippet 中创建一个变量来保存转换后的对象的好处是,可以更容易地看到转换在哪里进行。您不需要知道哪个操作需要对象的转换内容。

要转换Snippet中的对象,请使用以下语法:

ASSIGN varJSON="{myDynamic.asjson()}"

在需要 JSON 或 XML 数据的Studio操作的属性中,使用您在Snippet中使用的变量的名称。在语法示例中,您可以使用 varJSON 配置操作属性。

要转换操作属性中的对象,请使用对象名称和大括号中的 asjson()asxml() 函数配置操作属性。例如:{myDynamic.asjson()}

动态对象的所有成员都被视为字符串值,包括数字和布尔关闭 一种数据类型,它有两种可能值:真和假。值。对于不是字符串的值,您需要手动解析 JSON 以删除双引号。您可以使用 replace() 函数来执行此操作。

查看动态对象的内容

运行调试器时,可以在 Snippet 编辑器窗口中查看动态对象的内容。这允许您验证该对象是否包含代码中每一步应包含的数据。

  1. Studio 中,双击 Snippet 操作。
  2. 如果需要,添加片段代码。
  3. Debugger 选项卡上,单击变量树选项卡。
  4. Debugger 选项卡上,单击开始调试图标 旁边的向下箭头,然后选择单步执行一系列水平线,箭头从一条线指向其下一条线。。如果不想逐行单步执行代码,请单击开始调试图标。
  5. 单击单步 一系列水平线,箭头从一条线指向其下一条线。 图标,观察 Variables as Tree 选项卡上的内容。每次单击步骤时,该字段都会随上一行代码后脚本中的变量和对象而更新。如果单击开始调试,请跳过此步骤。
  6. 单步执行所有代码行后,或者单击开始调试时,Variables as Tree 选项卡会显示代码片段末尾的所有变量、对象及其内容。
  7. 您可以单击代码中任何字符串数组或动态对象旁边的 + 图标将其展开。如果内容是另一个数组或对象,您可以继续展开树以查看每个实体包含的内容。

脚本验证错误和动态对象

保存脚本时,Studio 会验证其中的所有信息。它检查的一个方面是脚本中引用的所有动态对象是否都在脚本中进行了声明。Studio 需要对正在验证的脚本中引用的所有对象进行对象声明。即使该对象在另一个脚本中进行了声明并被传递到正在验证的脚本中,它仍然会导致错误。如果脚本中有未声明的对象,则在保存时会看到 "函数“[name]”尚未定义” 错误。

有两种方法可以避免这种情况。一个选项是将带有TEST 变量的 IF 语句添加到引用该对象的代码片段中。在 IF 语句的大括号中,声明动态对象。例如:

IF TEST = 1
{
	DYNAMIC dynaObject
}
DYNAMIC dynaObject.prop = 1

第二个选项是将 SNIPPET 添加到仅包含对象声明的脚本中。如果将多个对象传递到脚本中,您可以在单个 SNIPPET 声明它们。这有助于保持脚本中的其他 SNIPPET 操作整洁。您不需要将此操作连接到脚本中的其他操作。脚本中存在它足以满足脚本在验证期间对对象声明的需要。