I would like to supplement the above with such parameters as STORAGEDEFAULT, SQLTABLENAME, and SQLPROJECTION: Storage and SQL Projection of Collection Properties

However a collection property is actually stored, the property can be projected as a column in the parent table, as a child table, or in both ways (as of release 2022.1, this is true for both list and array properties). To control this, you specify the SQLPROJECTION parameter of the property.

Try this:

ClassMethod test2()
{
  set tKP = ..%New()
  set tIdentifierSerial ##class(HS.Message.AddUpdateHubRequest).%OpenId(21986071).Identifiers
  zw tIdentifierSerial
  set tKP.IsSerial = 1
  set tKP.IsList = 1
  set tSerial tIdentifierSerial.GetObjectNext(.tKey)
  for {
    if tKey="" {quit}
    do tKP.SerialList.InsertObject(tSerial)
    set tSerial tIdentifierSerial.GetObjectNext(.tKey)
  }
  tKP.%Save()
}
SELECT JSON_ARRAYAGG(json_obj)
  FROM (SELECT TOP 5
            JSON_OBJECT(
              'Name':name
              ,'Age':age
              ,'DOB':to_char(dob,'Day DD Month YYYY')
            ) json_obj
           FROM sample.person
       )
SELECT JSON_ARRAYAGG(json_obj)
  FROM (SELECT JSON_OBJECT(
                'Name':name
                ,'Age':age
                ,'DOB':to_char(dob,'Day DD Month YYYY')
                ) json_obj
       FROM sample.person
       )
  WHERE %VID BETWEEN 1 AND 5

It is strange that the bug has not been fixed yet, because it is easy to fix it by adding one line to ##class(%JSON.Generator).GenerateMappingFromXdata():

<..>
For i=1:1:count {
  Set xdata=compiledclass.XDatas.GetAt(i)
  Set configName=xdata.Name
  If configName="" Continue ; since the Name field is required, how can it be empty?
  If xdata.MimeType'="text/xml" Continue
<..>

PS: by the way, I didn't quite understand why need to check "configName", given that "Name" is a required field. Any ideas?

For versions of Caché 5.0.x, try the following code:

#include %systemInclude

n

s list=$lb(
  "test",
  "for",
  "searching unknown strings here is a very long piece with enough characters to get a lowercase alpha as a $list marker",
  "items",
  "in",
  "aaatArGetwaaaa",
  "lists",
    $lb(
    "/subs",
    "/values",
    "nested list",
    "did you see that ""w"" before the third piece?",
    "Stuart Strickland",
    "Yaron Munz")
)

str=$$$UPPER($$cccvt^%Wpglo(list,$$$MaxStringLength,.warn))
; or
; s str=$$$UPPER($$listDump^%Wprim(list,9))

'warn {
 str=$e(str,3,$l(str)-2) ; remove << & >>
 ;s @("LIST="_str) zw LIST
 
 !,$f(str,$$$UPPER("Targetw"))
}

Result: 162

If you end up searching for globals that use $lb(), then you might find it useful: