文章
· 5 hr 前 阅读大约需 10 分钟

XML 到 HL7、FHIR 和 V2 的转换

什么是 XML?

XML (可扩展标记语言)是一种灵活的、基于文本的、独立于平台的格式,用于以结构合理 、人机可读的方式存储和传输数据 。XML 允许用户定义自定义标签来描述数据的含义和组织结构。例如:<book><title>The Hitchhiker's Guide</title></book>.

XML 文档具有自描述性,其结构是一棵分层的元素树。每个文档都有一个封装所有其他内容的根元素。元素可以包含文本、子元素和属性(提供补充信息的名-值对)。这些文档通常用 .xml 文件存储

这种结构的完整性可以通过以下方式实现:

  • DTD(文档类型定义):提供基本的验证规则。
  • XSD(XML 模式定义):提供高级规则,包括数据类型和约束。

转换 XML 文档

这部分内容介绍如下:

  1. 解析一般 XML 并将其转换为 HL7 标准。
  2. 解析 CCDA(综合临床文档架构)文档(XML)并将其转换为 HL7 格式。

在这些实施过程中,两种格式都会首先转换为 InterSystems IRIS SDA(标准化数据架构)格式。这被认为是一种标准、高效、不易出错的方法,因为它有效地利用了平台的 预置类。数据采用 SDA 格式后,可无缝转换为任何目标标准,如 HL7 v2FHIRCCDA

解析通用 XML 文档

通用 XML 文档具有自描述功能,可与 <name>、<sex> 和 <address> 等自定义标记一起使用。本节将介绍如何解析此类文档,并利用它通过中间 SDA(标准化数据架构)格式构建 HL7 消息。

在开始转换之前,您需要选择适当的工作流程:

  1. 推荐方法:转换为 SDA。这是最有效的方法。它包括将 XML 文档作为数据流读取,并在互操作性生产(Interoperability Production)中将其直接转换为 SDA(标准化数据架构)格式。这种做法是标准的,但对大规模数据处理非常有效。
  2. 替代方法:手动转换。您可以将 XML 文件作为对象读取,然后以编程方式执行转换。这种方法可提供更精细的控制,但实施起来通常更为复杂,可扩展性也较差。

读取 XML 文档

InterSystems IRIS 为顺利解析 XML 流提供了一套完整的类。其中包括以下两种关键方法:

  1. %XML.Reader:通过 %XML.Adaptor,提供了一种读取 XML 流并将其内容加载到对象中的编程方法。
  2. EnsLib.EDI.XML.Document:在互操作性生产中用于动态表示和解析 XML 文档。

 

使用 %XML.Reader 和 %XML.Adaptor 类

通过将 %XML.Adaptor 和 %XML.Reader 类结合使用,这是一种将 XML 文件或数据流解析为内存对象的强大而直接的技术。

让我们以下面的 XML 文件为例进行说明:

<Patient>
    <PatientID>12345</PatientID>
    <PatientName>DOE^JOHN</PatientName>
    <DateOfBirth>19900101</DateOfBirth>
    <Sex>M</Sex>
    <PatientClass>I</PatientClass>
    <AssignedPatientLocation>GEN^A1</AssignedPatientLocation>
    <AttendingDoctor>1234^DOCTOR^JOHN</AttendingDoctor>
</Patient>

首先,您必须创建一个表示 XML 文档结构的类定义。该类必须从 %XML.Adaptor扩展而来 。一旦加载了 XML,数据就可以作为对象的属性使用,从而方便访问和后续代码操作。

Class MyApp.Messages.PatientXML Extends (%Persistent, %XML.Adaptor)
{
Parameter XMLNAME = "Patient";
Property PatientID As %String;
Property PatientName As %String;
Property Age As %String;
Property DateOfBirth As %String;
Property Sex As %String;
Property PatientClass As %String;
Property AssignedPatientLocation As %String;
Property AttendingDoctor As %String;
ClassMethod XMLToObject(xmlStream As %Stream.Object = "", xmlString, filename = "C:\learn\hl7msg\test.xml")
{
	Set reader = ##class(%XML.Reader).%New() 

	// Begin processing of the XML input
	If filename'="" {
		Set sc=reader.OpenFile(filename) ; open the file directly
	}
	ElseIf $IsObject(xmlStream){
		Set sc=reader.OpenStream(xmlStream) ; parse from stream
	}
	ElseIf xmlString'="" {
		Set sc=reader.OpenString(xmlString) ; parse from stream
	}
	Else {
		Return $$$ERROR("No file name,string or stream found")
	}
  
	If $$$ISERR(sc) Do $system.OBJ.DisplayError(sc) Quit
	// Associate a class name with the XML element name
	;Do reader.Correlate(..#XMLNAME,$classname())
               Do reader.CorrelateRoot($classname())

	Do reader.Next(.patient,.sc) 
	If $$$ISERR(sc) Do $system.OBJ.DisplayError(sc) Quit
	ZWrite patient
}
}

XMLToObject 方法可解析文件、流或字符串中的 XML 数据,创建一个类实例,随后可用于程序转换或在互操作性产品中使用。

利用 EnsLib.EDI.XML.Document

EnsLib.EDI.XML.Document类提供了对任何XML内容的运行时和基于XPath的访问,而无需预定义的模式或类。当您需要在运行时动态提取值时,该类是理想之选。只需将您的 XML 加载到该类中,然后使用其方法通过 XPath 表达式快速访问元素即可。

通过保存对象实例,该类还能将 XML 文档直接持久化到EnsLib_EDI_XML.Document表中。

ClassMethod ParseXML(xmlfile As %String="")
{
	Set ediXMLDoc = ##class(EnsLib.EDI.XML.Document).ImportFromFile(xmlfile,,.sc)
	If $$$ISERR(sc) {
	  Quit
	}
	; pass XPath into GetValueAt method
	Write ediXMLDoc.GetValueAt("/Patient/PatiendID") ;returns the patient id
}

然后,您可以在类中声明 GetValueAt() 方法的返回值、局部变量或 JSON 格式。

XML 文件业务服务(EnsLib.EDI.XML.Service.FileService)使用此虚拟文档类进行解析操作。

注意: 在 InterSystems IRIS 中 通过 GetValueAt("XPath")获取过大 字符串 超过 3,641,144 个字符) 时,通常会收到 <MAXSTRING> 错误。您的代码应包括对这一限制的适当处理。

InterSystems IRIS 中的 XSD 模式加载

XSD(XML 模式定义)概述了 XML 文档的结构、元素、类型和验证规则,以确保数据的一致性和有效性。

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:element name="Patient">

<xs:complexType> <xs:sequence> <xs:sequence

<xs:sequence> <xs:element name="Patient

<xs:element name="PatientID" type="xs:string"/> <xs:element name="PatientID" type="xs:string"/>

<xs:element name="PatientName" type="xs:string"/> <xs:complexType

<xs:element name="DateOfBirth" type="xs:string"/> <xs:element name="DateOfBirth" type="xs:string"/>

<xs:element name="Sex" type="xs:string"/> <xs:sequence> </xs:sequence

</xs:sequence> </xs:complexType

</xs:complexType

</xs:element

</xs:schema

在 IRIS 中,加载 XSD 模式有几个主要目的:

  1. 验证: 它使传入的 XML 文档能够根据预定义的结构进行验证,确保数据的完整性。
  2. 生成 ObjectScript 类: 它能自动创建反映 XML 结构的 ObjectScript 类,从而简化程序访问。(您可以按照 Studio > Tools > AddIn > XMLSchema 向导加载 XSD 文件并生成类定义)。
  3. DTL 转换: 它有助于在数据转换语言(DTL)中进行基于模式的转换,从而实现不同格式之间的无缝数据映射。

导入 XML 模式

要将 XML 模式 (.xsd) 文件导入 InterSystems IRIS,请按以下步骤操作:

  1. 导航至 系统管理门户System Management Portal)
  2. 转到 互操作性 > 互操作 > XML > XML 模式结构Interoperability > Interoperate > XML > XML Schema Structures)
  3. 单击 导入(Import) 按钮。
  4. 在对话框中选择 schema.xsd 文件,然后单击 OK 完成导入。

所有导入的 XSD 模式都保存在每个命名空间内的 ^EnsEDI.XML.Schema 全局中。全局的第一个下标是模式名称,与管理门户中显示的名称相同。

源 XSD 文件的路径存储 在 ^EnsEDI.XML.Schema(<schema name>, "src",1) 中

重要提示:如果源文件从其原始位置删除,今后针对模式的任何验证尝试都将导致错误。

使用模式验证 XML

加载模式后,您可以使用下面的自定义代码根据模式验证 XML 文档。为此,您需要提供 XML 文件名称和模式名称作为参数:

/// XMLSchema – Imported schema or give the full path of the schema in the directory, e.g,/xml/xsd/patient.xsd
ClassMethod XMLSchemaValidation(xmlFileName As %String,XMLSchema As %Stirng="")
{
	Set xmlFileName="C:\test.xml"
	Set ediXMLdoc1 = ##class(EnsLib.EDI.XML.Document).ImportFromFile(xmlFileName,,.sc)
	If $$$ISERR(sc) Quit sc
	Set ediXMLdoc1.DocType=XMLSchema
	Return ediXMLdoc1.Validate()
}


嵌入式 Python 示例:

Class pySamples.XML Extends %RegisteredObject
{
ClassMethod GetError(er)
{
    Return $SYSTEM.Status.GetErrorText(er)
}

ClassMethod pyXMLShcemaValidation(xmlFileName = "C:\\hl7msg\\test.xml", XMLSchema = "Patient") [ Language = python ]
{
    import iris

    xml_status = iris.ref()
    ediXMLdoc = iris.cls("EnsLib.EDI.XML.Document").ImportFromFile(xmlFileName,1,xml_status)
    if xml_status.value!=1:
        print("XML Parsing error: ",iris.cls(__name__).GetError(xml_status))
    else:
        print(ediXMLdoc)
}
}

从对象获取模式:

Set object = ##class(MyApp.Messages.PatientXML).%New() ;replace your class here
Set XMLSchema = object.XMLSchema() ; this will return the XML schema for this class.

在探索 SDA 和其他医疗保健信息标准之前,让我们简要了解一下 CDA。

临床文档架构(CDA)

临床文档架构(CDAHL7 为电子临床文档 制定的 医疗保健标准 ,它定义了这些文档的结构、编码和交换方式,以确保人类和机器的可读性。

CDA 是一种 基于 XML 的标准 ,用于表示以下临床文档:

  • 出院摘要
  • 进展记录
  • 转诊信
  • 成像或实验室报告。

CDA 文档一般由 <ClinicalDocument> 元素封装,有两个主要部分:页眉和正文。

1.页眉(必填): 它位于 <ClinicalDocument> 和 <structuredBody> 元素之间。它包含文档的元数据,说明文档的内容、创建者、时间、原因和地点。

页眉中的关键元素:

  • 患者人口统计数据(recordTarget)、作者(医生、系统)、保管人(负责机构)、文档类型和模板 ID、相遇信息、法律验证器。

2.正文(必填): 它包含临床内容报告,由 <structuredBody> 元素封装,可以是非结构化的,也可以由结构化标记组成。它通常还分为递归嵌套的文档部分:

  • 非结构化:可能附带附件(如 PDF)的自由格式文本。

结构化:XML 部分,包含过敏、药物、问题、程序、化验结果等编码条目。

<ClinicalDocument>

  ... CDA Header ...

 <structuredBody>

    <section>

      <text>...</text>

      <observation>...</observation>

      <substanceAdministration>

        <supply>...</supply>

      </substanceAdministration>

      <observation>

        <externalObservation>...

        </externalObservation>

      </observation>

    </section>

    <section>

        <section>...</section>

    </section>

  </structuredBody>

</ClinicalDocument>

CCDA 到 HL7 的转换

在 InterSystems IRIS 中,将 CCDA(综合临床文档架构)文档转换为 HL7 v2 消息是一种常见的互操作性用例。虽然您仍然可以直接使用单步 DTL(数据转换语言)映射,但我们建议您选择称为 SDA 标准化数据架构)的中间数据格式 作为最稳健的方法。

步骤 1:C-CDA 到 SDA(XSLT)

第一步是将输入的 C-CDA 文档转换为 SDA 对象。(SDA 是一种供应商中立的临床数据模型,可简化临床信息的表示)。

  • 为什么要使用 SDA? C-CDA 是一种复杂的、分层的 XML 结构,有许多模板和部分。试图将其直接映射到 HL7 v2 信息的扁平、基于分段的配置极为困难,而且往往需要复杂而脆弱的逻辑。SDA 可作为简化的中间模型,从 C-CDA 中提取基本临床数据,避免了 XML 结构的复杂性。
  • 它是如何工作的? InterSystems IRIS 提供了一个预建 XSLT 文件库(通常位于 install-dir\CSP\xslt\SDA3 目录 ),用于将 C-CDA 转换为 SDA。这种转换通常需要使用业务流程或业务操作来调用正确的 XSLT。

所有 InterSystems 医疗保健产品都有一个 XSLT 库,用于将 CDA 文档转换为 SDA,反之亦然。您可以在 install-dir\CSP\xslt\ 查看可用的根级 XSLT 位置。

例如,CCDA-to-SDA 转换如下:

  • Consolidated CDA 1.1 CCD 到 SDA、 CCDAv21 到 SDA 转换。
  • 合并 CDA 2.1 CCD 到 SDA, SDA 到 C32v25 转换

从 SDA 转换或转换为 SDA

XML 加载到类对象后,就可以进行转换了。此时,您应创建自定义 DTL,将数据结构映射到 HS.SDA3.Container 或 HS.SDA3.* 特定类中,以构建 SDA 文档。

FHIR

利用 IRIS 内置的数据转换器进行 SDA 转换。您可以参考有关 FHIR 转换的文章。

HL7 V2

  • 您可以使用类方法 HS.Gateway.HL7.HL7ToSDA3.GetSDA(),以编程方式将 HL7 信息转换为 SDA。例如,执行 ##class(HS.Gateway.HL7.HL7ToSDA3).GetSDA(pRequest,.tSDA).
  • 注意:目前还没有直接从 SDA 转换回 HL7 v2 的编程方法。

关键类、表、全局、链接

  • %XML.*.cls:所有与 XML 相关的类都可以在此软件包中找到。
  • Ens.Util.XML.Validator:该类包含验证 XML 的实用方法。
  • EnsLib.EDI.XML.Service.FileService:它是一个业务服务主机。
  • %XML.XSLT.Transformer:
  • %XML.Writer:
  • %XML.Reader:
  • %XML.Adaptor:
  • %XML.Document:
  • %XML.Schema:
  • %XML.String:它是 XML 的数据类型类。
  • %XML.SAX.Parser
  • HS.SDA3.Container:它是一个主要的 SDA 容器类。
  • HS.SDA3.*.cls:SDA 类。

表格

  • EnsLib_EDI_XML.Document:该表用于存储 EDI XML 文档。

Globals

  • ^EnsEDI.XML.Schema:该全局存储 XSD 模式。
  • ^EnsLib.EDI.XML.DocumentD: 该全局保存 EnsLib_EDI_XML.Document 表的数据。

本文概述了 XML基本原理。

讨论 (0)1
登录或注册以继续