第四章 Caché JSON 處理資料型別
文章目錄
第四章 Caché JSON 處理資料型別
使用%GetTypeOf()
返回值的資料型別
可以使用%GetTypeOf()
方法獲取動態實體成員的資料型別。動態物件屬性或陣列元素可以具有下列任何一種資料型別:
- 物件資料型別:
- array 動態陣列引用
- object 動態物件引用
- oref 對不是動態實體的cache物件的引用
- 文字值:
- number 數字
- string 字串或字串文字的表示式
- JSON 文字值:
- boolean JSON文字 true或 false
- null JSON文字 null
- 沒有資料型別:
- unassigned 屬性或元素存在,但沒有賦值。
物件使用%GetTypeOf
當對物件使用此方法時,引數是屬性的名稱。例如:
/// d ##class(PHA.OP.MOB.Test).TestGetTypeObjects()
ClassMethod TestGetTypeObjects()
{
set dynobj={"prop1":123,"prop2":[7,8,9],"prop3":{"a":1,"b":2}}
set iter = dynobj.%GetIterator()
while iter.%GetNext(.name) {write !,"Datatype of "_name_" is "_(dynobj.%GetTypeOf(name))}
}
DHC-APP>d ##class(PHA.OP.MOB.Test).TestGetTypeObjects()
Datatype of prop1 is number
Datatype of prop2 is array
Datatype of prop3 is object
對陣列使用%GetTypeOf
當對陣列使用此方法時,引數是元素的索引。下面的示例研究一個稀疏陣列,其中元素2沒有賦值。該示例使用for
迴圈,因為%GetNext()
將跳過未分配的元素:
/// d ##class(PHA.OP.MOB.Test).TestGetTypeArray()
ClassMethod TestGetTypeArray()
{
set dynarray = [12,34]
set dynarray."3" = "final"
write dynarray.%ToJSON()
for index = 0:1:3 {write !,"Datatype of "_index_" is "_(dynarray.%GetTypeOf(index))}
}
DHC-APP>d ##class(PHA.OP.MOB.Test).TestGetTypeArray()
[12,34,null,"final"]
Datatype of 0 is number
Datatype of 1 is number
Datatype of 2 is unassigned
Datatype of 3 is string
區分陣列或物件和oref
動態實體的資料型別將是陣列或物件。不是動態實體的Caché 物件將是資料型別oref
。在下面的示例中,物件dyn
的每個屬性都是這三種資料型別之一。
屬性dynobject
是class %DynamicObject
,屬性dynarray
是%DynamicArray
,屬性streamobj
是%Stream.GlobalCharacter
:
/// d ##class(PHA.OP.MOB.Test).TestGetTypeOref()
ClassMethod TestGetTypeOref()
{
s a="字串"
set dyn={"dynobject":{"a":1,"b":2},"dynarray":[3,4],"streamobj":(##class(%Stream.GlobalCharacter).%New()),"a":(a)}
set iterator=dyn.%GetIterator()
while iterator.%GetNext(.key,.val) { write !, "Datatype of "_key_" is: "_dyn.%GetTypeOf(key) }
}
DHC-APP>d ##class(PHA.OP.MOB.Test).TestGetTypeOref()
Datatype of dynobject is: object
Datatype of dynarray is: array
Datatype of streamobj is: oref
Datatype of a is: string
注意: 在 json字串中引用Caché oject變數 可以在()
中使用
用%Set()
或%Push()
重寫覆蓋預設資料型別
預設情況下,Caché 自動將%Set()
或%Push()
值引數解釋為物件資料型別(物件、陣列或oref)或Caché 文字資料型別(字串或數字)。
不能直接將JSON字面量null
、true
或false
作為值傳遞,因為引數被解釋為Caché字面量或表示式。
例如,下面的程式碼丟擲一個錯誤,因為Caché 將true解釋為一個變數名:
/// d ##class(PHA.OP.MOB.Test).TestDatatype()
ClassMethod TestDatatype()
{
s o={}
do o.%Set("prop3",true)
write o.%ToJSON()
}
DHC-APP> d ##class(PHA.OP.MOB.Test).TestDatatype()
do o.%Set("prop3",true)
^
<UNDEFINED>zTestDatatype+2^PHA.OP.MOB.Test.1 *true
Caché 對null
使用“”
(一個空字串),對boolean false使用0,對boolean true使用非零數字。為了處理這個問題,%Set()
和%Push()
使用可選的第三個引數來指定值的資料型別。
第三個引數可以是JSON boolean,也可以是null
。例如:
/// d ##class(PHA.OP.MOB.Test).TestDatatypeThird()
ClassMethod TestDatatypeThird()
{
write {}.%Set("a",(2-4)).%Set("b",0).%Set("c","").%ToJSON(),!
write {}.%Set("a",(2-4),"boolean").%Set("b",0,"boolean").%Set("c","","null").%ToJSON(),!
}
DHC-APP>d ##class(PHA.OP.MOB.Test).TestDatatypeThird()
{"a":-2,"b":0,"c":""}
{"a":true,"b":false,"c":null}
第三個引數也可以是字串或數字,如果值可以解釋為一個數字:
/// d ##class(PHA.OP.MOB.Test).TestDatatypeThirdArgument()
ClassMethod TestDatatypeThirdArgument()
{
write [].%Push("023"_"04").%Push(5*5).%ToJSON(),!
write [].%Push(("023"_"04"),"number").%Push((5*5),"string").%ToJSON(),!
}
DHC-APP>d ##class(PHA.OP.MOB.Test).TestDatatypeThirdArgument()
["02304",25]
[2304,"25"]
解析JSON空值和布林值
在JSON語法中,值true
、false
和null
與值1
、0
和“”
(空字串)不同,但是Caché ObjectScript沒有這種區別。當從元素或屬性檢索JSON值時,總是將它們轉換為與object script相容的值。這意味著JSON true總是返回為1,false為0,null為“”。在大多數情況下,這將是理想的結果,因為返回值可以在Caché 表示式中使用,而無需首先將其從JSON格式轉換過來。動態實體在內部保留原始的JSON或Caché 值,因此可以在必要時使用%GetTypeOf()
來標識實際的資料型別。
在下面的示例中,動態陣列建構函式指定JSON真、假、空值、數字和字串文字值,以及ObjectScript動態表示式(計算結果以Caché 布林值1和0):
/// d ##class(PHA.OP.MOB.Test).TestBooleanValues()
ClassMethod TestBooleanValues()
{
set test = [true,1,(1=1),false,0,(1=2),"",null]
write test.%ToJSON()
}
DHC-APP>d ##class(PHA.OP.MOB.Test).TestBooleanValues()
[true,1,1,false,0,0,"",null]
正如上面所看到的,建構函式中分配的值被儲存在結果的動態陣列中,並在序列化為JSON字串時被正確顯示。
下面的示例檢索並顯示陣列值JSON值true
、false
和null
被轉換為與Caché 相容的值1
、0
和“”
:
/// d ##class(PHA.OP.MOB.Test).TestBooleanValues()
ClassMethod TestBooleanValues()
{
set test = [true,1,(1=1),false,0,(1=2),"",null]
write test.%ToJSON(),!
set iter = test.%GetIterator()
while iter.%GetNext(.key,.val){write "/"_val_"/ ",!}
}
DHC-APP>d ##class(PHA.OP.MOB.Test).TestBooleanValues()
[true,1,1,false,0,0,"",null]
/1/
/1/
/1/
/0/
/0/
/0/
//
//
本例使用%GetNext()
,但是如果使用%get()
、%Pop()
或點語法檢索值,則會得到相同的結果。
必要時,可以使用%GetTypeOf()
方法來發現值的原始資料型別。例如:
/// d ##class(PHA.OP.MOB.Test).TestBooleanValues()
ClassMethod TestBooleanValues()
{
set test = [true,1,(1=1),false,0,(1=2),"",null]
write test.%ToJSON(),!
set iter = test.%GetIterator()
while iter.%GetNext(.key,.val){write "/"_val_"/ ",!}
set iter = test.%GetIterator()
while iter.%GetNext(.key,.val) {write !,key_": /"_test.%Get(key)_"/ = "_test.%GetTypeOf(key)}
}
DHC-APP>d ##class(PHA.OP.MOB.Test).TestBooleanValues()
[true,1,1,false,0,0,"",null]
/1/
/1/
/1/
/0/
/0/
/0/
//
//
0: /1/ = boolean
1: /1/ = number
2: /1/ = number
3: /0/ = boolean
4: /0/ = number
5: /0/ = number
6: // = string
7: // = null
注意:動態物件中的資料型別。 雖然本章主要討論動態陣列,但是相同的資料型別轉換也適用於動態物件值。如果將動態陣列測試定義為動態物件,則本節中的示例將完全相同:
set test = {"0":true,"1":1,"2":(1=1),"3":false,"4":0,"5":(1=2),"6":"","7":null}
除了這一行之外,示例程式碼都不需要修改。此物件中的屬性名是與原始陣列的索引號對應的數字字串,因此即使輸出也是相同的。
解決Null、空字串和未賦值
儘管可以將JSON null
值賦給元素或屬性,但該值總是以“”
(Caché空字串)的形式返回。如果試圖獲取未分配元素的值,也將返回空字串。可以使用%GetTypeOf()
來識別每種情況下的實際資料型別。
本例將測試一個包含JSON null
值和空字串的稀疏陣列。雖然陣列元素2沒有賦值,但它在JSON字串中表示為null
:
/// d ##class(PHA.OP.MOB.Test).TestArrayNull()
ClassMethod TestArrayNull()
{
set array = [null,""]
do array.%Set(3,"last")
write array.%ToJSON()
}
DHC-APP> d ##class(PHA.OP.MOB.Test).TestArrayNull()
[null,"",null,"last"]
在大多數情況下,將使用%GetNext()
來檢索陣列值,但是本例使用for迴圈來返回未分配的值,而%GetNext()
將跳過這些值。
最後一個元素的索引號是array.%Size()-1
,但是迴圈計數器被故意設定為超過陣列的末尾:
/// d ##class(PHA.OP.MOB.Test).TestArrayNull()
ClassMethod TestArrayNull()
{
set array = [null,""]
do array.%Set(3,"last")
write array.%ToJSON(),!
for i=0:1:(array.%Size()) {write !,i_". value="""_array.%Get(i)_""" type="_array.%GetTypeOf(i)}
}
DHC-APP> d ##class(PHA.OP.MOB.Test).TestArrayNull()
[null,"",null,"last"]
0. value="" type=null
1. value="" type=string
2. value="" type=unassigned
3. value="last" type=string
4. value="" type=unassigned
在本例中,%Get()
在四種不同的情況下返回空字串:
- 元素0是一個JSON空值,
%GetTypeOf()
將其標識為資料型別null
。 - 元素1是一個空字串,它被標識為資料型別字串。
- 元素2沒有值,被標識為未分配的資料型別。
- 雖然元素3是陣列中的最後一個元素,但是示例嘗試為不存在的元素4獲取一個資料型別,該元素也被標識為未分配的資料型別。有效的陣列索引號總是小於
array.%Size()
。
注意:null
和unassigned
之間的區別是Caché 後設資料,當動態實體序列化為JSON字串時,這些後設資料不會被保留。所有未分配的元素都將序列化為null
值。
相關文章
- flutter json資料處理FlutterJSON
- Hive處理Json資料HiveJSON
- spark處理json資料DemoSparkJSON
- 處理json格式的資料JSON
- JDBC 處理CLob和Blob型別資料JDBC型別
- MySQL JSON資料型別操作MySqlJSON資料型別
- JSON 資料型別(轉載)JSON資料型別
- ETLCloud支援的資料處理型別包括哪些?Cloud型別
- JS指令碼批次處理TS資料型別JS指令碼資料型別
- Python資料處理(一):處理 JSON、XML、CSV 三種格式資料PythonJSONXML
- python 資料處理(字串擷取、()\[]\{}資料型別、{}字典資料取值)Python字串資料型別
- 如何處理http返回型別為206的資料HTTP型別
- JNI開發流程與引用資料型別的處理資料型別
- C#中處理JSON資料的方式C#JSON
- flutter json_annotation和json_serializable處理json資料序列化FlutterJSON
- mysql 5.7 json 型別 json 陣列型別 普通字串型別 10w資料 查詢速度差異MySqlJSON型別陣列字串
- 05 Windows批處理中的字串和布林資料型別Windows字串資料型別
- 06 Windows批處理之整數和浮點資料型別Windows資料型別
- java 如何簡單快速處理 json 中的資料JavaJSON
- C++實現對Json資料的友好處理C++JSON
- Python處理JSONPythonJSON
- 第四章 資料的預處理與特徵構建(續)特徵
- Mybatis讀取和儲存json型別的資料MyBatisJSON型別
- 拋磚系列之-MySQL中的資料型別JSONMySql資料型別JSON
- 一文說透 MySQL JSON 資料型別(收藏)MySqlJSON資料型別
- 陣列轉json後的資料型別問題陣列JSON資料型別
- 使用Java處理JSON結構化資料 -Advanced Web MachineryJavaJSONWebMac
- 程式錯誤型別及其處理型別
- 使用ajax請求傳送複雜的json資料型別,並解決fastjson解析複雜的json資料型別的問題JSON資料型別AST
- Python資料處理(二):處理 Excel 資料PythonExcel
- js資料型別之基本資料型別和引用資料型別JS資料型別
- 幾個例子理解不同資料型別的堆疊記憶體處理資料型別記憶體
- 資料型別: 資料型別有哪些?資料型別
- size_t 資料型別的好處資料型別
- gson-plugin告別Json資料型別不一致(一)PluginJSON資料型別
- MySQL 數值型別溢位處理MySql型別
- Laravel 處理 MySQL geometry 空間型別LaravelMySql型別
- 複合型別(json)型別JSON