You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Firely C#返回的FHIR JSON解析为自定义eReferral对象

解决Firely C#客户端解析FHIR JSON提取指定字段的问题

首先定义自定义的eReferral类示例:

public class eReferral
{
    public string ReferralReference { get; set; }
    public string Priority { get; set; }
    public string Specialty { get; set; }
    public string PatientId { get; set; }
    public string PatientName { get; set; } // 可选,根据需求添加
}

方案一:使用FhirJsonNode正确定位字段

如果坚持使用FhirJsonNode,核心注意点是FHIR扩展字段必须通过完整URL匹配,而非仅字段名。假设你的FHIR响应是Bundle(批量转诊)或单个ReferralRequest资源,代码如下:

using Hl7.Fhir.Serialization;

string fhirJson = "你的FHIR JSON响应字符串";
var rootNode = FhirJsonNode.Parse(fhirJson);
var referrals = new List<eReferral>();

// 处理Bundle类型响应
if (rootNode["resourceType"].ToString() == "Bundle")
{
    foreach (var entryNode in rootNode["entry"].Elements())
    {
        var resourceNode = entryNode["resource"];
        if (resourceNode["resourceType"].ToString() != "ReferralRequest")
            continue;

        var eRef = new eReferral();

        // 提取转诊引用(优先取fullUrl,无则取资源ID)
        eRef.ReferralReference = entryNode["fullUrl"]?.ToString() ?? resourceNode["id"].ToString();

        // 提取患者信息(subject字段是Reference类型)
        var subjectNode = resourceNode["subject"];
        if (subjectNode != null && !string.IsNullOrEmpty(subjectNode["reference"]?.ToString()))
        {
            eRef.PatientId = subjectNode["reference"].ToString().Split('/').Last();
            // 若Bundle包含Patient资源,可在此解析患者名称
        }

        // 提取Priority扩展(替换为你的实际扩展URL)
        var priorityExt = resourceNode["extension"]?
            .Elements()
            .FirstOrDefault(e => e["url"].ToString() == "http://your-institution.com/fhir/extension/referral-priority");
        if (priorityExt != null)
        {
            // 假设priority是Code类型,根据实际类型调整(如valueString)
            eRef.Priority = priorityExt["valueCode"]?.ToString();
        }

        // 提取Specialty扩展(替换为你的实际扩展URL)
        var specialtyExt = resourceNode["extension"]?
            .Elements()
            .FirstOrDefault(e => e["url"].ToString() == "http://your-institution.com/fhir/extension/referral-specialty");
        if (specialtyExt != null)
        {
            // 假设specialty是CodeableConcept类型,取第一个coding的display
            eRef.Specialty = specialtyExt["valueCodeableConcept"]?["coding"]?.Elements().First()["display"]?.ToString();
        }

        referrals.Add(eRef);
    }
}
// 处理单个ReferralRequest资源
else if (rootNode["resourceType"].ToString() == "ReferralRequest")
{
    var eRef = new eReferral();
    eRef.ReferralReference = rootNode["id"].ToString();

    // 提取患者信息
    var subjectNode = rootNode["subject"];
    if (subjectNode != null)
    {
        eRef.PatientId = subjectNode["reference"].ToString().Split('/').Last();
    }

    // 提取Priority扩展
    var priorityExt = rootNode["extension"]?
        .Elements()
        .FirstOrDefault(e => e["url"].ToString() == "你的priority扩展URL");
    if (priorityExt != null)
    {
        eRef.Priority = priorityExt["valueCode"]?.ToString();
    }

    // 提取Specialty扩展
    var specialtyExt = rootNode["extension"]?
        .Elements()
        .FirstOrDefault(e => e["url"].ToString() == "你的specialty扩展URL");
    if (specialtyExt != null)
    {
        eRef.Specialty = specialtyExt["valueCodeableConcept"]?["coding"]?.Elements().First()["display"]?.ToString();
    }

    referrals.Add(eRef);
}

关键注意事项

  1. 扩展URL必须完全匹配:FHIR的扩展通过唯一URL标识,不能仅用"priority"或"specialty"作为匹配条件,必须使用响应中实际的完整URL。
  2. 字段类型匹配:根据FHIR响应中字段的实际类型调整取值(比如priority可能是valueCode或valueString,specialty可能是valueCodeableConcept)。
  3. 空值判断:所有字段都要加null检查,避免空引用异常。

方案二:使用Firely强类型模型(推荐)

Firely提供了FHIR资源的强类型类,无需手动操作JSON节点,代码更简洁且不易出错。

首先安装对应FHIR版本的NuGet包(如R4版本):

Install-Package Hl7.Fhir.R4

然后编写解析代码:

using Hl7.Fhir.Model;
using Hl7.Fhir.Serialization;

string fhirJson = "你的FHIR JSON响应字符串";
var parser = new FhirJsonParser();
Bundle bundle = parser.Parse<Bundle>(fhirJson);

var referrals = new List<eReferral>();

foreach (var entry in bundle.Entry)
{
    if (entry.Resource is ReferralRequest referralRequest)
    {
        var eRef = new eReferral();

        // 提取转诊引用
        eRef.ReferralReference = entry.FullUrl ?? referralRequest.Id;

        // 提取患者信息
        if (referralRequest.Subject != null && !string.IsNullOrEmpty(referralRequest.Subject.Reference))
        {
            eRef.PatientId = referralRequest.Subject.Reference.Split('/').Last();
            // 若Bundle包含Patient资源,直接查找解析患者名称
            var patientEntry = bundle.Entry.FirstOrDefault(e => e.Resource is Patient && e.Resource.Id == eRef.PatientId);
            if (patientEntry?.Resource is Patient patient)
            {
                eRef.PatientName = patient.Name.FirstOrDefault()?.Text;
            }
        }

        // 提取Priority扩展
        var priorityExt = referralRequest.Extension.FirstOrDefault(e => e.Url == "你的priority扩展URL");
        if (priorityExt != null && priorityExt.Value is Code priorityCode)
        {
            eRef.Priority = priorityCode.Value;
        }

        // 提取Specialty扩展
        var specialtyExt = referralRequest.Extension.FirstOrDefault(e => e.Url == "你的specialty扩展URL");
        if (specialtyExt != null && specialtyExt.Value is CodeableConcept specialtyCc)
        {
            eRef.Specialty = specialtyCc.Coding.FirstOrDefault()?.Display;
        }

        referrals.Add(eRef);
    }
}

强类型方案优势

  • 编译时类型检查,避免手动写JSON路径的错误
  • 直接利用Firely封装的FHIR资源类和扩展处理逻辑,代码更简洁
  • 自动处理FHIR复杂类型(如CodeableConcept、Reference)的解析

内容的提问来源于stack exchange,提问作者Richard Housham

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 04:33:05