基于 XSLT 的互联互通临床文档到 FHIR 资源转换
国家卫健委互联互通成熟度评测中的临床共享文档,作为医疗信息交换的重要载体,采用了XML标准的文档格式。随着医疗信息化的发展,FHIR(Fast Healthcare Interoperability Resources)作为新一代医疗信息交换标准,因其简洁性、灵活性和RESTful架构,逐渐成为医疗数据交换的理想选择。将共享文档文档转换为FHIR资源,能够有效促进不同医疗系统间的数据互通,提升医疗信息的利用价值。
XSLT(可扩展样式表语言转换)是一种用于将XML文档转换为其他XML文档或文本格式的语言。在医疗数据转换场景中,XSLT凭借其强大的XML处理能力,成为共享文档到FHIR转换的理想工具。
我们知道共享文档文档是一种结构化的XML文档,通常包含以下主要部分:
- 文档头(Document Header):包含文档元数据,如文档类型、创建时间、作者等
- 临床数据部分(Clinical Sections):按章节组织的临床信息,如问题列表、用药记录、检查报告等
- 数据条目(Entries):具体的临床数据项,如诊断、药物、检验结果等
FHIR则采用了资源导向的设计理念,每个临床概念都被建模为独立的资源,通过RESTful API进行访问。FHIR资源具有以下特点:
- 模块化设计:每个资源专注于特定的临床领域,如Patient(患者)、Condition(疾病)、MedicationRequest(用药申请)等
- 灵活的数据结构:支持复杂的数据类型和嵌套结构
- 丰富的语义表达:通过代码系统和扩展机制提供标准化的术语支持
互联互通共享文档到FHIR的转换并非简单的格式转换,而是需要在保持临床语义的前提下,将共享文档的文档结构映射到FHIR的资源模型。这需要深入理解两种标准的数据模型和语义。
在Intersystems IRIS中,我们内嵌了我司创建的SDA医疗数据模型,此模型也是以xml为结构,并且在IRIS中已经开箱即用地实现了SDA模型到FHIR资源的转化,所以在IRIS互联互通套件中把共享文档向FHIR资源转化的思路就变成了由互联互通共享文档->SDA文档->FHIR资源的转化流程。(关于我司SDA数据模型的介绍参见https://docs.intersystems.com/irisforhealth20251/csp/docbook/Doc.View.cl...)
下面是一个使用XSLT将互联互通文档中的信息转换为SDA再使用IRIS开箱即用功能转为FHIR资源的示例:
在互联互通套件中,我们已经实现了由互联互通文档向SDA转化的xslt,这些xslt在https://gitee.com/jspark/CCHDist 代码仓库的https://gitee.com/jspark/CCHDist/tree/master/image-iris/src/hccns/Setting/HCC 部分可以找到,文件名为HCC2SDA.xsl,其内引用的其他xlst模版也在相同文件夹下。
互联互通文档转化为SDA文档的示例代码:
Method HCCToSDA(pHCC As %Stream.Object, ByRef pSDA As %Stream.Object) As %Status
{
Set tSC = $$$OK
Try
{
If $ISOBJECT(pSDA) &&(pSDA.%IsA("%Stream.Object"))
{
}
Else
{
Set tSC = $$$ERROR(-10000,"Input parameter pSDA is not a stream")
Quit
}
Set tSlash = $Case($system.Version.GetOS(),"Windows":"\",:"/")
Set tXSL="file:///"_$SYSTEM.Util.InstallDirectory()_"csp"_tSlash_"xslt"_tSlash_"HCC"_tSlash_"HCC2SDA.xsl"
Set tSC = ..Transformer.Transform(pHCC,tXSL,.tSDA)
Quit:($$$ISERR(tSC))
D pSDA.CopyFrom(tSDA)
if (..Debug=1)
{
Set ..FileGUID = $Case($system.Version.GetOS(),"Windows":"\",:"/")_$SYSTEM.Util.CreateGUID()
Set tSDAFile=##class(%Stream.FileCharacter).%New()
Set tSC=tSDAFile.LinkToFile(..DebugPath_..FileGUID_".XML")
Set tSDAFile.TranslateTable="UTF8"
Do tSDAFile.Write(pSDA.Read())
Do tSDAFile.%Save(),tSDAFile.%Close()
Kill tSDAFile
}
}
Catch ex
{
Set tSC=ex.AsStatus()
}
Quit tSC
}
由SDA转化为FHIR资源的示例代码:
Method SDAToFHIR(pSDA As %Stream.Object, ByRef pFHIR As %Stream.Object) As %Status
{
If ($ISOBJECT(pSDA) && pSDA.%IsA("%Stream.Object"))
{}
Else
{
Quit $$$ERROR(-10000,"Input parameter pSDA is not a stream")
}
Set tSC = $$$OK
Try
{
Set tFHIR = ##class(HS.FHIR.DTL.Util.API.Transform.SDA3ToFHIR).TransformStream(pSDA,"HS.SDA3.Container","R4")
If ('$ISOBJECT(tFHIR))
{
K tFHIR
Set tSC = $$$ERROR(-10000,"SDA transfer to FHIR error!")
Quit
}
Else
{
Set:($Get(pFHIR)="") pFHIR=##class(%Stream.TmpCharacter).%New()
Do pFHIR.Write(tFHIR.bundle.%ToJSON())
Do tFHIR.%Close()
if ..Debug=1
{
Set tFHIRFile=##class(%Stream.FileCharacter).%New()
Set tSC=tFHIRFile.LinkToFile(..DebugPath_..FileGUID_".JSON")
Set tFHIRFile.TranslateTable="UTF8"
Do pFHIR.Rewind()
Do tFHIRFile.Write(pFHIR.Read())
D tFHIRFile.%Save(),tFHIRFile.%Close()
K tFHIRFile
}
}
}
Catch ex
{
Set tSC=ex.AsStatus()
}
Quit tSC
}
综合起来互联互通文档转化为FHIR资源的示例,这里pFHIR的输出就是得到的fhir资源:
Method HCCToFHIR(pHCC, ByRef pFHIR) As %Status
{
If ($ISOBJECT(pHCC) && pHCC.%IsA("%Stream.Object"))
{}
Else
{
Quit $$$ERROR(-10000,"Input parameter pHCC is not a stream")
}
Set tSDA = ##class(%Stream.GlobalCharacter).%New()
Set tSC = ..HCCToSDA(pHCC,.tSDA)
Quit:($$$ISERR(tSC)) tSC
Set tSC = ..SDAToFHIR(tSDA,.pFHIR)
Quit tSC
}
在我们的IRIS互联互通套件里实现了由共享文档生成再到FHIR资源的转化的全部流程,https://gitee.com/jspark/CCHDist 可以在这个代码仓库中找到IRIS互联互通套件的代码实现以及相关介绍文档。