Try   HackMD

Firely Validation

Firely最近發表了新版的Validation,以下為範例程式的測試結果與原始碼分析。這次Firely提供了一個UI介面的展示程式,對於非開發者而言,應該也是另一個選項。不過,目前還沒有看到單獨下載UI應用程式的選項,應該也是不久之後的事。

Demo程式與操作步驟

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Demo畫面分成三個部分:

  • Instance
    按下[Load],選擇將驗證的FHIR檔案,顯示FHIR檔案的內容。
    按下[Validate],啟用Validator將驗證結果顯示於[Validation results]

  • Validation results
    顯示驗證結果,可按[Copy to clipboard]將驗證結果儲存到剪貼簿。

  • Settings
    profiles和terminology的相關設定,default profiles為FhirRelease.R4

原始碼分析

官網提供的範例如下:

https://docs.fire.ly/projects/Firely-NET-SDK/en/latest/validation/profile-validation.html

var packageServer = "https://packages.simplifier.net";
var fhirRelease = FhirRelease.STU3;
var packageResolver = FhirPackageSource.CreateCorePackageSource(ModelInfo.ModelInspector, fhirRelease, packageServerUrl);
var resourceResolver = new CachedResolver(packageResolver);
var terminologyService = new LocalTerminologyService(resourceResolver);

var validator = new Validator(resourceResolver, terminologyService);
var testOrganization = new Organization { };

var profile = Canonical.ForCoreType("Organization").ToString();
var result = validator.Validate(testOrganization, profile);

嚴格來說,這應該算是一個示意,重點在於邏輯的展示。由上面範例程式可以理解,整個FHIR Valication的核心是validator,建構validator的必要條件是Package resolver和Terminology Service。Package Resolver可以從外部匯入,也可以設定為local directory;同樣的,Terminology Service亦可以從外部讀取或是從已知的profile取得。

實務上,resolver會有多個資料參考來源,因此必須使用MutiResolver,假設我們已經將某一個IG的profile下載到local端(C:\\Project\\Firely-NET-SDK-Labs\\profile),透過MutiResolver建構validator的範例程式如下:

var packageSource = FhirPackageSource.CreateCorePackageSource(ModelInfo.ModelInspector, FhirRelease.R4, "https://packages.simplifier.net");
IAsyncResourceResolver  _coreSource = new CachedResolver(packageSource);
var directorySource = new CachedResolver(new DirectorySource("C:\\Project\\Firely-NET-SDK-Labs\\profile",
                            new DirectorySourceSettings { IncludeSubDirectories = true }));

var profileSource = new MultiResolver(directorySource, _coreSource);
var terminologySource = new LocalTerminologyService(profileSource);

var validator = new Validator(profileSource, terminologySource);

polygolt範例

對於想要簡化程式邏輯的開發人員,可快速參考以下程式。
https://github.com/hongyu0324/Firely-NET-SDK-Labs/blob/master/src/Lab %238-2 FHIR Validation.dib

程式碼深入分析

MultiResolver可以包含多個packages,以電子處方簽為例,由於電子處方簽所使用的IG是https://silcoet.ntunhs.edu.tw/Healthycloud/StructureDefinition-Bundle-EP.html實際上是繼承tw core ig v0.2.1https://twcore.mohw.gov.tw/ig/twcore/因此需要多個packages。以下做法可達到要求:

var directorySource1 = new CachedResolver(new DirectorySource(profileDirectory.FullName,
                            new DirectorySourceSettings { IncludeSubDirectories = true }));

                        var directorySource2 = new CachedResolver(new DirectorySource("D:\\Hongyu\\Project\\data\\profiles\\tw-core-ig\\v0.2.1\\package",
                            new DirectorySourceSettings { IncludeSubDirectories = true }));

                        // Finally, we combine both sources, so we will find profiles both from the core zip as well as from the directory.
                        // By mentioning the directory source first, anything in the user directory will override what is in the core zip.
                        result = new MultiResolver(directorySource1,directorySource2, _coreSource);

MultiResolver的輸入參數是由ISyncOrAsyncResourceResolver組成的List,常用的ResourceResolver為CachedResolver,由FhirPackageSource、DirectorySource或ZipSource構成,分別是應用在simplifier package source,下載之Package Directory與Zip壓縮檔等不同情境。

Terminology也是區分為ExternalTerminologyService和LocalTerminologyService兩種,分別處理內建的Terminology與外部服務。