InterSystems ObjectScript语法包括对JSON的集成支持(https://json.org/)。一组快速、简单、强大的功能使您可以像处理对象或表一样轻松地处理JSON数据结构:
- 使用JSON的ObjectScript语法,您可以使用标准的ObjectScript赋值语句而不是方法调用来在运行时创建和更改动态实体。对象属性和数组元素的值可以指定为JSON字符串文字或ObjectScript动态表达式。
- 两个类,
%Library.DynamicObject
和%Library.DynamicArray
,为封装和使用标准JSON数据结构提供了一种简单、高效的方法。这些类的实例称为动态实体。 - 动态实体包含JSON序列化(动态实体和规范JSON格式之间的转换)、迭代、数据类型、创建/读取/更新/删除操作以及其他有用功能的方法。
1.1 运行中的JSON特性
以下是ObjectScript中可用的JSON功能的一些示例:
-
在运行时创建和操作动态实体
您可以创建动态实体并在运行时为其定义任意模式:
set dynObject1 = ##class(%DynamicObject).%New() set dynObject1.SomeNumber = 42 set dynObject1.SomeString = "a string" set dynObject1.SomeArray = ##class(%DynamicArray).%New() set dynObject1.SomeArray."0" = "an array element" set dynObject1.SomeArray."1" = 123
-
使用JSON构造函数创建动态实体
您还可以通过指定JSON字符串来创建动态实体。JSON构造函数
{}
和[]
可以用来代替%New()
构造函数。例如,可以使用set x=[]
而不是set x=##class(%DynamicArray).%New()
创建动态数组。与%New()
不同,JSON构造函数也可以采用指定属性或元素的JSON文本字符串。这意味着您可以使用以下简单的赋值语句创建与上一示例中dynObject1相同的对象:set dynObject2 = {"SomeNumber":42,"SomeString":"a string"} set dynObject2.SomeArray = ["an array element",123]
此示例为每个构造函数使用一个语句,但数组构造函数也可以很容易地嵌套在对象构造函数中。
为了证明
dynObject1
和dynObject2
是相同的,我们可以将它们显示为%ToJSON()
方法返回的序列化JSON字符串:write "object 1: "_dynObject1.%ToJSON(),!,"object 2: "_dynObject2.%ToJSON() object 1: {"SomeNumber":42,"SomeString":"a string","SomeArray":["an array element",123]} object 2: {"SomeNumber":42,"SomeString":"a string","SomeArray":["an array element",123]}
-
使用动态表达式定义值
构造函数
{}
和[]
中包含的文本必须使用有效的JSON语法,只有一个例外。对于元素或属性的值,可以使用括号中的表达式,而不是JSON文本。此ObjectScript动态表达式(相当于set语句的右侧)将在运行时求值并转换为有效的JSON值。本示例中的动态表达式包括对$ZDATE
函数的调用:set dynObj = { "Date":($ZD($H,3)) }
当我们检索
dynObj.Date
,使用表达式值:write "Value of dynamic expression is: "_dynObject.Date Value of dynamic expression is: 2016-07-27
(有关这些主题的详细讨论,请参阅“动态表达式和点语法”)。
-
在动态实体和规范JSON字符串之间转换
动态实体具有序列化方法,允许它们转换为JSON字符串或从JSON字符串转换。在下面的示例中,使用一个文本构造函数创建一个动态对象,并调用该对象的
%ToJSON()
方法将其序列化为myJSONstring
:set myJSONstring = {"aNumber":(21*2),"aDate":($ZD($H,3)),"anArray":["string",123]}.%ToJSON()
这个序列化的JSON对象可以像任何其他字符串一样存储和检索。类方法
%FromJSON()
和%FromJSONFile()
可以从任何源获取有效的JSON字符串,并将其转换为动态对象。以下代码将myJSONstring
反序列化为动态对象myObject
,并使用%ToJSON()
显示它:set myObject = ##class(%DynamicAbstractObject).%FromJSON(myJSONstring) write myObject.%ToJSON() {"aNumber":42,"aDate":"2016-08-29","anArray":["string",123]}
-
链动态实体方法
某些动态实体方法可以链接。本例创建了一个包含两个元素的动态数组,然后使用
%Push()
方法将三个元素添加到数组的末尾。对%ToJSON()
的最后一个链式调用将显示序列化字符串:set dynArray = ["a","b"] write dynArray.%Push(12).%Push({"a":1,"b":2}).%Push("final").%ToJSON() ["a","b",12,{"a":1,"b":2},"final"]
(有关可链接方法的更多信息,请参阅“方法链接”)。
-
迭代和数据类型发现
动态实体方法也用于迭代和数据类型发现等目的。本例创建了两个JSON字符串,将其中一个字符串反序列化为
dynEntity
(任何一个都可以),然后为dynEntity
实体获取迭代器:set arrayStr = [12,"some string",[1,2]].%ToJSON() set objectStr = {"a":12,"b":"some string","c":{"x":1,"y":2}}.%ToJSON() set dynEntity = {}.%FromJSON(objectStr) set itr = dynEntity.%GetIterator()
对于while循环的每次迭代,
%GetNext()
将返回key中的属性名或数组索引以及val中的成员值。%GetTypeOf()
的返回值是一个字符串,指示值的数据类型:while itr.%GetNext(.key,.val) {write !,key_": "_"/"_val_"/, type: "_dynEntity.%GetTypeOf(key)} a: /12/, type: number b: /some string/, type: string c: /1@%Library.DynamicObject/, type: object
(有关这些和相关方法的更多信息,请参阅“迭代和稀疏数组”和“使用数据类型”)。
1.2 动态实体方法概述
动态实体方法可分为以下类别:
-
创建、读取、更新、删除
%Set()
可以更改现有动态实体成员(属性或元素)的值,也可以创建新成员并为其赋值。%Remove()
删除现有成员。%Get()
检索成员的值。有关详细信息,请参见“创建和修改动态实体”。 -
迭代和稀疏阵列
%GetIterator()
返回一个迭代器,其中包含指向动态实体每个成员的指针。%GetNext()
返回迭代器标识的成员的键和值,并将光标前进到下一个成员。%Size()
返回成员数(包括稀疏数组中未分配的元素)。%IsDefined()
测试成员是否具有赋值。有关详细信息,请参阅“迭代和稀疏阵列”。 -
堆栈函数
%Push()
将新元素添加到动态数组的末尾。%Pop()
删除数组的最后一个元素并返回其值。这些方法不适用于动态对象,因为对象属性不是以可预测的顺序存储的。有关详细信息,请参阅“将%Push
和%Pop
用于动态阵列”。 -
JSON序列化和反序列化
%FromJSON()
转换JSON字符串,%FromJSONFile()
将存储在文件中的JSON字符串转换为动态实体。%ToJSON()
将动态实体序列化为规范JSON字符串。有关详细信息,请参阅“将动态实体转换为JSON和从JSON转换为JSON”。 -
数据类型信息
%GetTypeOf()
返回一个字符串,指示指定成员值的数据类型。%Set()
和%Push()
提供了可选的第三个参数,用于显式指定值的数据类型。有关详细信息,请参阅“使用数据类型”。
请参阅“动态实体方法快速参考”,了解每种方法的描述和更多信息的链接。