New post

検索

Article
· 13 hr ago 5m read

JSON2Class, the JSON to ObjectScript converter you've always wanted

How many times have you had to receive or generate a JSON and wished you could work on it using DTLs without having to deal with DynamicObjects trying to remember the name of each field? Do you want to break down and make your giant JSON file more digestible?

In my case, never, but I thought that someone might find it useful to have a feature that captures your JSON and breaks it down into a series of ObjectScript classes that you can work with more easily and conveniently.

Well then...behold JSON2Class in all its glory!

How does JSON2Class work?

It's very simple: it leverages Embedded Python's capabilities to slice and parse your JSON and generate the associated classes. These generated classes will be of two types:

  • %Persistent: for the main or root class.
  • %SerialObject: for all subclasses that will be attached to the main one.

To do this, it takes into consideration the following points:

Reserved words

Not just any property name that comes in your JSON is acceptable, so it will be modified by adding to the end of the JSON name, so that " language" will become " languageJSON".

Special characters

Special characters such as "_" are also  removed, so "patient_name" will now be called "patientname".

%JSONFIELDNAME

To prevent the class from changing its name when it is converted back to JSON, the %JSONFIELDNAME attribute has been added to the properties whose names are modified, allowing us to maintain the original label when exporting it to JSON.

Generating the classes

All the functionality is contained within the Utils.JSON2Class  class , and to invoke the generation process we have the following method:

ClassMethod Convert(
    json As %String,
    basePackage As %String = "App.Model",
    rootClassName As %String = "Root",
    outDir As %String = "/shared/generated"
) As %String

Let's analyze the attributes of the ClassMethod:

  • json: This will be our template JSON that we want to generate.
  • basePackage: The package in which all the classes will be implemented.
  • rootClassName: The name of the persistent class that will act as the root.
  • outDir: The local directory where the class files will be generated.

Example:

We started with a typical JSON, such as a FHIR resource of type patient:

{
	"resourceType": "Patient",
	"id": "example",
	"identifier": [
		{
			"use": "usual",
			"type": {
				"coding": [
					{
						"system": "http://terminology.hl7.org/CodeSystem/v2-0203",
						"code": "MR"
					}
				]
			},
			"system": "urn:oid:1.2.36.146.595.217.0.1",
			"value": "12345",
			"period": {
				"start": "2001-05-06"
			},
			"assigner": {
				"display": "Acme Healthcare"
			}
		}
	],
	"active": true,
	"name": [
		{
			"use": "official",
			"family": "Chalmers",
			"given": [
				"Peter",
				"James"
			]
		},
		{
			"use": "usual",
			"given": [
				"Jim"
			]
		},
		{
			"use": "maiden",
			"family": "Windsor",
			"given": [
				"Peter",
				"James"
			],
			"period": {
				"end": "2002"
			}
		}
	],
	"telecom": [
		{
			"use": "home"
		},
		{
			"system": "phone",
			"value": "(03) 5555 6473",
			"use": "work",
			"rank": 1
		},
		{
			"system": "phone",
			"value": "(03) 3410 5613",
			"use": "mobile",
			"rank": 2
		},
		{
			"system": "phone",
			"value": "(03) 5555 8834",
			"use": "old",
			"period": {
				"end": "2014"
			}
		}
	],
	"gender": "male",
	"birthDate": "1974-12-25",
	"_birthDate": {
		"extension": [
			{
				"url": "http://hl7.org/fhir/StructureDefinition/patient-birthTime",
				"valueDateTime": "1974-12-25T14:35:45-05:00"
			}
		]
	},
	"deceasedBoolean": false,
	"address": [
		{
			"use": "home",
			"type": "both",
			"text": "534 Erewhon St\nPeasantVille, Rainbow, Vic3999",
			"line": [
				"534 Erewhon St"
			],
			"city": "PleasantVille",
			"district": "Rainbow",
			"state": "Vic",
			"postalCode": "3999",
			"period": {
				"start": "1974-12-25"
			}
		}
	],
	"contact": [
		{
			"relationship": [
				{
					"coding": [
						{
							"system": "http://terminology.hl7.org/CodeSystem/v2-0131",
							"code": "N"
						}
					]
				}
			],
			"name": {
				"family": "du Marché",
				"_family": {
					"extension": [
						{
							"url": "http://hl7.org/fhir/StructureDefinition/humanname-own-prefix",
							"valueString": "VV"
						}
					]
				},
				"given": [
					"Bénédicte"
				]
			},
			"additionalName": [
				{
					"use": "nickname",
					"given": [
						"Béné"
					]
				}
			],
			"telecom": [
				{
					"system": "phone",
					"value": "+33 (237) 998327"
				}
			],
			"address": {
				"use": "home",
				"type": "both",
				"line": [
					"534 Erewhon St"
				],
				"city": "PleasantVille",
				"district": "Rainbow",
				"state": "Vic",
				"postalCode": "3999",
				"period": {
					"start": "1974-12-25"
				}
			},
			"additionalAddress": [
				{
					"use": "work",
					"line": [
						"123 Smart St"
					],
					"city": "PleasantVille",
					"state": "Vic",
					"postalCode": "3999"
				}
			],
			"gender": "female",
			"period": {
				"start": "2012"
			}
		}
	],
	"managingOrganization": {
		"reference": "Organization/1"
	}
}

Let's now look at the Root object, which will be our main patient class:

Let's now look at the Root object, which will be our main patient class:

Class App.Model.Root Extends (%Persistent, %JSON.Adaptor)
{

Property resourceType As %String;
Property idJSON As %String(%JSONFIELDNAME = "id");
Property identifier As list Of App.Model.Root.Identifier;
Property active As %Boolean;
Property name As list Of App.Model.Root.Name;
Property telecom As list Of App.Model.Root.Telecom;
Property gender As %String;
Property birthDate As %String;
Property deceasedBoolean As %Boolean;
Property address As list Of App.Model.Root.Address;
Property contact As list Of App.Model.Root.Contact;
Property managingOrganization As App.Model.Root.ManagingOrganization;
}

Et voila! We can now store our JSON as a regular object.

Next steps

It's not bad to be able to automatically generate the classes, but it would be interesting to be able to automatically transform the JSON into an instance of the classes we have created, taking into account the particularities of the property names.

We'll leave it in the to-do pile

homer simpson sits on a couch next to a stack of papers and a can of duff beer

Discussion (0)1
Log in or sign up to continue
Article
· 13 hr ago 5m read

JSON2Class, el conversor de JSON a ObjectScript que siempre deseaste

¿Cuantas veces habéis tenido que recibir o generar un JSON y habéis añorado el poder trabajar sobre él haciendo uso de DTLs y sin tener que ir manejando DynamicObjects intentando recordar cual era el nombre de cada campo?

¿Deseas trocear y hacer más digerible tu gigantesco JSON?

En mi caso, nunca, pero he pensado que a alguien le podría resultar de utilidad una funcionalidad que capture tu JSON y lo descomponga en una serie de clases de ObjectScript con las que puedas trabajar de forma más cómoda y sencilla.

Pues bien...¡contemplad el JSON2Class en toda su gloria!

¿Cómo funciona JSON2Class?

Muy sencillo, aprovecha las capacidades de Embedded Python para trocear y analizar tu JSON y generar las clases asociadas al mismo. Estas clases generadas serán de dos tipos:

  • %Persistent: para la clase principal o root.
  • %SerialObject: para todas las subclases que colgarán de la principal.

Para ello tiene en consideración los siguientes puntos:

Palabras reservadas

No nos vale cualquier nombre de propiedad que venga en tu JSON, por lo que se modificará añadiendo al final del nombre JSON, de tal forma que "language" pasará a ser "languageJSON".

Carácteres especiales

También se eliminan los carácteres especiales como "_", por lo que "patient_name" pasará a denominarse "patientname".

%JSONFIELDNAME

Para evitar que a la hora de convertir nuevamente la clase a JSON se han añadido a las propiedades que ven modificados sus nombres el atributo %JSONFIELDNAME que nos permite mantener la etiqueta original cuando lo exportemos a JSON.

Generando las clases

Toda la funcionalidad se encuentra dentro de la clase Utils.JSON2Class y para invocar el proceso de generación disponemos del método:

ClassMethod Convert(
    json As %String,
    basePackage As %String = "App.Model",
    rootClassName As %String = "Root",
    outDir As %String = "/shared/generated"
) As %String

Analicemos los atributos del ClassMethod:

  • json: será nuestro json de plantilla que queremos generar. 
  • basePackage: el package sobre el que se implementarán todas las clases. 
  • rootClassName: el nombre de la clase persistente que ejercerá de raíz.
  • outDir: directorio local donde se van a generar los ficheros de las clases.

Ejemplo:

Hemos partido de un JSON típico como sería un recurso FHIR de tipo paciente:

{
	"resourceType": "Patient",
	"id": "example",
	"identifier": [
		{
			"use": "usual",
			"type": {
				"coding": [
					{
						"system": "http://terminology.hl7.org/CodeSystem/v2-0203",
						"code": "MR"
					}
				]
			},
			"system": "urn:oid:1.2.36.146.595.217.0.1",
			"value": "12345",
			"period": {
				"start": "2001-05-06"
			},
			"assigner": {
				"display": "Acme Healthcare"
			}
		}
	],
	"active": true,
	"name": [
		{
			"use": "official",
			"family": "Chalmers",
			"given": [
				"Peter",
				"James"
			]
		},
		{
			"use": "usual",
			"given": [
				"Jim"
			]
		},
		{
			"use": "maiden",
			"family": "Windsor",
			"given": [
				"Peter",
				"James"
			],
			"period": {
				"end": "2002"
			}
		}
	],
	"telecom": [
		{
			"use": "home"
		},
		{
			"system": "phone",
			"value": "(03) 5555 6473",
			"use": "work",
			"rank": 1
		},
		{
			"system": "phone",
			"value": "(03) 3410 5613",
			"use": "mobile",
			"rank": 2
		},
		{
			"system": "phone",
			"value": "(03) 5555 8834",
			"use": "old",
			"period": {
				"end": "2014"
			}
		}
	],
	"gender": "male",
	"birthDate": "1974-12-25",
	"_birthDate": {
		"extension": [
			{
				"url": "http://hl7.org/fhir/StructureDefinition/patient-birthTime",
				"valueDateTime": "1974-12-25T14:35:45-05:00"
			}
		]
	},
	"deceasedBoolean": false,
	"address": [
		{
			"use": "home",
			"type": "both",
			"text": "534 Erewhon St\nPeasantVille, Rainbow, Vic3999",
			"line": [
				"534 Erewhon St"
			],
			"city": "PleasantVille",
			"district": "Rainbow",
			"state": "Vic",
			"postalCode": "3999",
			"period": {
				"start": "1974-12-25"
			}
		}
	],
	"contact": [
		{
			"relationship": [
				{
					"coding": [
						{
							"system": "http://terminology.hl7.org/CodeSystem/v2-0131",
							"code": "N"
						}
					]
				}
			],
			"name": {
				"family": "du Marché",
				"_family": {
					"extension": [
						{
							"url": "http://hl7.org/fhir/StructureDefinition/humanname-own-prefix",
							"valueString": "VV"
						}
					]
				},
				"given": [
					"Bénédicte"
				]
			},
			"additionalName": [
				{
					"use": "nickname",
					"given": [
						"Béné"
					]
				}
			],
			"telecom": [
				{
					"system": "phone",
					"value": "+33 (237) 998327"
				}
			],
			"address": {
				"use": "home",
				"type": "both",
				"line": [
					"534 Erewhon St"
				],
				"city": "PleasantVille",
				"district": "Rainbow",
				"state": "Vic",
				"postalCode": "3999",
				"period": {
					"start": "1974-12-25"
				}
			},
			"additionalAddress": [
				{
					"use": "work",
					"line": [
						"123 Smart St"
					],
					"city": "PleasantVille",
					"state": "Vic",
					"postalCode": "3999"
				}
			],
			"gender": "female",
			"period": {
				"start": "2012"
			}
		}
	],
	"managingOrganization": {
		"reference": "Organization/1"
	}
}

Y al ejecutar el conversor hemos obtenido las siguientes clases:

Veamos ahora el objeto Root, que será nuestra clase principal del paciente:

Class App.Model.Root Extends (%Persistent, %JSON.Adaptor)
{

Property resourceType As %String;

Property idJSON As %String(%JSONFIELDNAME = "id");

Property identifier As list Of App.Model.Root.Identifier;

Property active As %Boolean;

Property name As list Of App.Model.Root.Name;

Property telecom As list Of App.Model.Root.Telecom;

Property gender As %String;

Property birthDate As %String;

Property deceasedBoolean As %Boolean;

Property address As list Of App.Model.Root.Address;

Property contact As list Of App.Model.Root.Contact;

Property managingOrganization As App.Model.Root.ManagingOrganization;

}

Et voila! Ya podemos almacenar nuestro JSON como un objeto al uso.

Siguientes pasos

No esta mal poder generar automáticamente las clases, pero será interesante poder transformar automáticamente el JSON a una instancia de las clases que hemos creado teniendo en cuenta las particularidades de los nombres de las propiedades.

Lo dejaremos en la pila de cosas por hacer.

homer simpson sits on a couch next to a stack of papers and a can of duff beer

Discussion (0)1
Log in or sign up to continue
Article
· 13 hr ago 2m read

Reseñas en Open Exchange - #63

Si uno de vuestros paquetes en OEX recibe una reseña, OEX os notificará únicamente sobre vuestro propio paquete. La valoración refleja la experiencia del revisor con el estado del paquete en el momento de la reseña.
Es como una “fotografía” del estado en ese momento y podría haber cambiado desde entonces. Las reseñas realizadas por otros miembros de la comunidad se marcan con un * en la última columna.

Además, el revisor puede enviar Pull Requests en GitHub cuando encuentra un problema que se puede solucionar. Algunas puden ser aceptadas y fusionadas, y otras simplemente ignoradas.
Así que, si habéis realizado un cambio importante y esperáis que la reseña cambie, simplemente avisad al revisor.

# Package Review Stars IPM Docker *
1 IRIS OpenTelemetry Demo impressive 7 containers concert 5.5   y  
2 DBdashboard impressive catch 5.0   y *
3 DBfree super multi instance monitoring 5.0   y *
4 IRIS-EchoServer-WebSockets echo inside IRIS 5.0   y *
5 iris-health-fhir-agentic-demo not just big but great 5.0   y *
6 ML Made Easy : IntegratedML an excellent training for beginners 5.0   y  
7 restoreUI a pleasure to work with 5.0 y y  
8 WebSocketsSample hidden treasure detected 5.0      
9 CSV-to-MS-OFX rare subject 4.8   y *
10 GeoDatas works partially 3.5   y  
11 CommunityEns requires some adjustments 3.3   y  
12 ALPHA LOGISTICS partner posting *      
13 ERP Plenum partner posting *      

 

NOTA:
Si alguna reseña no os resulta legible, podría estar pendiente de aprobación por los administradores de OEX.

Discussion (0)1
Log in or sign up to continue
Discussion
· 14 hr ago

Proven results Best Urologist in chickpet

The Best Urologist in chickpet, Dr. Anil Kumar T, delivers advanced treatment for urological diseases and tumors using minimally invasive techniques. Patients benefit from reduced recovery time, improved comfort, and structured care plans. His patient-centered consultations, accurate diagnosis, and individualized care ensure effective outcomes. Known for consistent results and ethical practice, he has earned a strong reputation in Chickpet. Individuals seeking reliable and professional urology care trust his expertise, experience, and dedication to patient health.

Discussion (0)1
Log in or sign up to continue
Announcement
· 19 hr ago

我们即将推出的 InterSystems EHR 集成专家认证考试需要测试员

InterSystems EHR 社区的朋友们,大家好、

InterSystems Certification目前正在为 InterSystems EHR 集成专家开发认证考试,如果您符合下面的考试候选人描述,我们希望您能参与考试的测试!考试将于 2025 年 11 月 10 日开始接受测试。

注意, 非 InterterSystems 员工必须完成 TrakCare Healthcare Messaging Framework (HMF) 课程,才有资格参加测试版考试。 有关资格的更多信息,请参阅下面 "考试详情 "下的 "所需培训"。

测试版测试将于 2026 年 3 月 15 日结束。

 

作为测试版测试员,我有哪些责任?

作为测试员,我们要求您在 2026 年 1 月 15 日之前安排并参加考试。考试将在在线监考环境中免费进行(所有测试版测试者均免交每次考试 150 美元的标准费用)。然后,InterSystems 认证团队将对所有测试数据进行仔细的统计分析,以确定考试的合格分数。测试结果的分析通常需要 6-8 周的时间,一旦及格分数确定,您将收到 InterSystems Certification 通知您结果的电子邮件。如果您的考试成绩达到或超过及格分数,您将获得认证!

注意:测试分数是完全保密的。

有兴趣参加吗?请阅读下面的考试详情。

 

考试详情

考试名称:InterSystems EHR 集成专家

注:InterSystems 目前提供两款 EHR 产品,由同一团队基于相同的系统和流程打造。TrakCare 是基础平台,而 IntelliCare 则在此基础上增加了其他特性和功能。这两种产品共享相同的核心基础设施。因此,在提及两种产品的共同功能(如考试题目列表中涉及的功能)时,使用 InterSystems EHR 一词

考生说明: 具有以下经验的 IT 专业人员:

  • InterSystems EHR 的一般基础知识、
  • InterSystems EHR 数据模型、
  • 行业标准集成信息格式(HL7v2、FHIR、SDA3、IHE)、
  • 以及医疗保健信息传递框架 (HMF)

推荐实践经验: 至少 6-12 个月的 InterSystems EHR 集成全职工作经验,熟悉 HL7 消息传递概念和 InterSystems ObjectScript。

所需培训:

非 InterSystems 员工必须完成TrakCare Healthcare Messaging Framework 课程,才有资格参加 InterSystems EHR 集成专家认证考试。该课程仅适用于符合以下条件的合作机构

  • 拥有有效的 InterSystems EHR 许可证,或者是有效 EHR 实施中的 TrakCare 实施合作伙伴,并且
  • 目前正在使用 InterSystems EHR 和医疗保健信息传递框架

如对资格有任何疑问,请联系 certification@intersystems.com

如果您是 InterSystems 员工,对 beta 测试感兴趣,请联系 certification@intersystems.com

建议准备工作: 复习以下内容:

考试练习题: 此处提供了一套练习题,以便考生熟悉出题格式和方法。

 

问题数量: 49

考试时间: 2 小时

考试形式:试题有两种形式:选择题和多选题。

测试版测试的系统要求

  • 正常工作的摄像头和麦克风
  • 双核 CPU
  • 至少 2 GB 内存
  • 至少 500 MB 可用磁盘空间
  • 最低网速:
    • 下载 - 500kb/s
    • 上传 - 500kb/s

考试题目和内容

考试包含的试题涵盖如下考试题目表所示的指定角色领域:

题目

副标题

知识、技能和能力

1.证明掌握 InterSystems 电子健康记录集成所需的基本概念 1.1 进入 InterSystems 电子病历系统并定位测试病人和数据
  1. 描述 EPR 的组件
  2. 解释 Edition 如何提供特定地区的功能
  3. 使用 InterSystems EHR 进行病人和病程查询,并执行其他基本操作
  2.检查和配置 InterSystems EHR 的基本设置
  1. 描述配置管理器中的重要项目(如站点代码、系统路径等)
  2. 确定配置集成相关代码表的步骤
  3. 切换 InterSystems 电子健康记录功能
  3.检查和解释 InterSystems EHR 数据模型和数据定义,并执行基本 SQL 查询
  1. 使用 InterSystems EHR 数据字典用户界面检查并解释数据定义和表之间的关系
  2. 使用 InterSystems 类引用功能检查和解释数据定义、关系和全局存储
  3. 对病人、病程和订单项目执行基本 SQL 查询
  4.检查并解释集成安全配置设置
  1. 描述 InterSystems EHR 应用程序安全模型
  2. 使用 InterSystems IRIS 的管理门户检查安全设置
  5.解释 HL7 V2 要求
  1. 描述常见的 HL7 V2 消息类型(如 ADT、SIU、REF 和 ORM/ORU)
  2. 将 InterSystems EHR 触发事件与 HL7 V2 报文类型相关联
  3. 描述 HL7 V2 数据与 InterSystems EHR 数据模型之间的映射关系
  6.解释 HL7 FHIR 要求
  1. 命名常见的 HL7 FHIR 资源
  2. 将 HL7 FHIR 资源与 InterSystems EHR 数据模型关联起来
  7.识别 SDA 中的元素
  1. 识别 SDA 结构中的重要元素
  2. 使用 InterSystems 类参考指南检查 SDA 定义
  3. 将 SDA 元素与 HL7 V2 报文段和字段相关联
2.使用保健信息传送框架(HMF)进行 InterSystems 电子健康记录集成 1.证明掌握 HMF 基本概念
  1. 使用 HMF(InterSystems EHR/SDA3)临床摘要
  2. 使用 HMF 外部搜索和合并工作流程
  3. 使用 HMF FHIR 管理器
  2.设计和配置 HMF 产品
  1. 根据集成解决方案设计/架构确定定义和配置 HMF 的步骤
  2. 检查现有 HMF 配置设置
  3. 列出每个生成产品的角色(系统、路由器、网关)
  4. 根据集成解决方案设计准备 HMF 产品和接口
  3.开发和定制 HMF 产品
  1. 开发自定义入站/出站方法
  2. 改进生成的 DTL 代码
  3. 创建扩展
  4. 使用集成管理器启用/禁用事件触发器/制作
  5. 配置出站查询接口并进行流程调用,以便从外部系统搜索患者信息
  6. 在容器和患者级别创建额外的 SDA 元素(扩展
  4.部署 HMF 解决方案
  1. 本地部署与远程部署的对比
  5.管理和监控 HMF 产品
  1. 使用集成历史用户界面检查集成事件和 SDA 内容
  2. 查看每个产品(系统、路由器和网关)中生成的业务服务和业务流程的配置设置(如端口、URL、文件路径等)
  3. 使用生产管理器和 InterSystems IRIS 消息查看器确定生产状态
  4. 使用 InterSystems IRIS 管理门户中的 Visual Trace 检查每个生产的消息工作流
  6.排除 HMF 产品故障
  1. 检查并解释 ^zTRAK("HMF") 全局中的低级 HMF 跟踪详情
  2. 检查 HMF 生产设置
  3. 制定解决策略
3.为外部访问和访问第三方应用程序配置 InterSystems EHR 1. 1.配置入站数据访问
  1. 使用外部 SQL 工具(如 WinSQL 执行 SQL 查询)
  2.配置出站数据访问
  1. 针对外部表或视图创建并运行 SQL 查询
  3.使用 SOAP 网络服务
  1. 编写 InterSystems ObjectScript 代码以调用外部 SOAP 网络服务
  2. 使用 SOAP 向导创建代理客户端
  4.链接到外部浏览器
  1. 为 InterSystems EHR 配置外部浏览器,以启动外部 PACS
  2. 将外部浏览器与接收位置关联
  5.使用 InterSystems EHR REST API
  1. 检索 InterSystems EHR API Swagger 文档
  2. 使用 API 管理器配置 InterSystems EHR REST API
  3. 审核 REST API 历史记录

有兴趣参加吗? 我们鼓励已完成 TrakCare HealthCare Messaging Framework 课程的合格考生通过我们的考试交付平台安排和参加考试。 我们鼓励有意参加测试版但未接受过所需培训的 非 InterSystems 员工在 2026 年 1 月 7 日之前完成该课程。对于有兴趣参加测试版的内部候选人,请联系certification@intersystems.com 了解您的资格。

如有任何疑问,请联系certification@intersystems.com。

Discussion (0)1
Log in or sign up to continue