NotesJSONNavigator:LotusScript 原生 JSON 解析,不必再做字串手術

NotesJSONNavigator:LotusScript 原生 JSON 解析,不必再做字串手術

2026.07.18 約 643 字

如果你做 Domino 夠久,會記得用 LotusScript 解析 JSON 的苦法:Evaluate@Explode、或一有值裡含逗號就爆掉的 regex 式字串手術。從 Domino 10.0.1 起有了正經的答案 — NotesJSONNavigator,「一個用來解析 JSON 資料的 LotusScript 類別」。它交給你一棵由物件、陣列、值組成的型別化樹,讓你直接導覽。API 很乾淨;唯一的摩擦是幾個跟你會猜的不一樣的命名。


重點摘要

  • Set nav = session.CreateJSONNavigator(jsonString$) 把 JSON 解析成一棵可導覽的樹。輸入可以是空字串(用來建 JSON)、一個 JSON 字串、或一個 NotesStream只支援 UTF-8)。Domino 10.0.1 引入。
  • GetElementByName(name)GetNthElement(index)1-based)、或 GetElementByPointer("/path/to/value")(JSON Pointer)導覽。每個都回傳一個 NotesJSONElement
  • 一個 NotesJSONElementNameTypeValue。當 Type 是 object 或 array,.Value 就是一個 NotesJSONObjectNotesJSONArray,你接著迭代它。
  • 命名意外 #1: 迭代到處都是 GetFirstElement / GetNextElement — 不是 GetFirstItem/GetItem
  • 命名意外 #2: 建 JSON 時,AppendElement(value, name)value 在前、name 在後;用 Stringify() 序列化整棵樹。

解析與導覽

從一個 JSON 字串建 navigator,然後用名稱、JSON Pointer、或迭代來取值:

Sub Initialize
Dim session As New NotesSession
Dim nav As NotesJSONNavigator
Dim el As NotesJSONElement
Dim arr As NotesJSONArray
Dim item As NotesJSONElement
Dim testJSON As String
testJSON = |{ "variable1":"value1", "variable2":"value2",| _
& | "myarray":["An","array","of","strings"],| _
& | "myobject":{"property1":"yourValue1"} }|
Set nav = session.CreateJSONNavigator(testJSON)
' 用名稱 -> "value2"
Set el = nav.GetElementByName("variable2")
Print "variable2 = " & el.Value
' 用 JSON Pointer -> "yourValue1"
Set el = nav.GetElementByPointer("/myobject/property1")
Print "property1 = " & el.Value
' 下降進巢狀陣列:element 的 Value 就是 NotesJSONArray
Set el = nav.GetElementByName("myarray")
Set arr = el.Value
Set item = arr.GetFirstElement()
While Not (item Is Nothing)
Print "array item = " & item.Value
Set item = arr.GetNextElement()
Wend
End Sub

這段展示兩件事。第一,GetElementByPointer 用 JSON Pointer 語法(/myobject/property1)直接跳到一個巢狀值 — 比一個節點一個節點下降乾淨太多。第二,你往深處走的方式是 element.Value:當一個 element 的 Type 是 object 或 array,它的 Value 不是純量 — 是你接著走訪的 NotesJSONObject / NotesJSONArray

Element 型別系統

每個 NotesJSONElement 回報一個 Type,你拿它跟 JSONELEM_TYPE_* 常數比對:

常數意義
JSONELEM_TYPE_OBJECT1一個 JSON 物件(ValueNotesJSONObject
JSONELEM_TYPE_ARRAY2一個 JSON 陣列(ValueNotesJSONArray
JSONELEM_TYPE_STRING3字串
JSONELEM_TYPE_NUMBER4數字
JSONELEM_TYPE_BOOLEAN5布林
JSONELEM_TYPE_UTF8_BYTEARRAY6UTF-8 位元組陣列
JSONELEM_TYPE_EMPTY64空 / null

注意沒有獨立的 null 型別 — JSON null 對映到 JSONELEM_TYPE_EMPTY。讀 Value 之前先依 Type 分支,這樣你才知道拿到的是純量還是容器:

Select Case el.Type
Case JSONELEM_TYPE_STRING, JSONELEM_TYPE_NUMBER, JSONELEM_TYPE_BOOLEAN
Print el.Name & " = " & el.Value
Case JSONELEM_TYPE_OBJECT
Dim obj As NotesJSONObject
Set obj = el.Value ' 下降
Case JSONELEM_TYPE_ARRAY
Dim arr As NotesJSONArray
Set arr = el.Value
End Select

NotesJSONObjectNotesJSONArray 各自提供 Size(元素數量)加上同一套 GetFirstElement / GetNextElement / GetNthElement 迭代器 — 整個家族一致。

建 JSON — 注意參數順序

navigator 除了消費 JSON 也產生 JSON。從一個空 navigator 開始、append、再 Stringify

Dim nav As NotesJSONNavigator
Set nav = session.CreateJSONNavigator("")
Call nav.AppendElement("value1", "variable1") ' AppendElement(value, name) — value 在前
Call nav.AppendElement(123, "count")
Print nav.Stringify() ' => {"variable1":"value1","count":123}

陷阱是參數順序:AppendElement(value, name) — value 在前、name 在後,跟多數人第一次會打的相反。AppendArray(name)AppendObject(name) 回傳一個新的 NotesJSONArray / NotesJSONObject,你用同樣方式填。做完 Stringify() 把整棵樹序列化回 JSON 字串(沒有 ToJSONString/GetJSONString — 方法是 Stringify)。

同類別在其他語言

Domino API 裡沒有直接對應物,這點值得直說。lotus.domino 沒有 JSONNavigator 類別 — Java 開發者會拿標準函式庫(com.google.gsonorg.json、或 com.ibm.commons.util.io.json)。SSJS/XPages 也沒有 JSONNavigator 物件;它用全域的 fromJson() / toJson() 輔助函式。所以這裡 relatedJavarelatedSsjs 留空 — NotesJSONNavigator 是 LotusScript 的便利、沒有 1:1 對映,這也是對慣常「LS 是窮親戚」框架的一個漂亮反轉:在 JSON 這塊,LotusScript 拿到了一個專門打造的原生 parser,另外兩個反而靠通用函式庫。(本文是 JSON element/array/object 深度文的姊妹篇。)

參考來源

← 回到文章列表