Firely Validation === Firely最近發表了新版的Validation,以下為範例程式的測試結果與原始碼分析。這次Firely提供了一個UI介面的展示程式,對於非開發者而言,應該也是另一個選項。不過,目前還沒有看到單獨下載UI應用程式的選項,應該也是不久之後的事。 Demo程式與操作步驟 --- ![Validator - 1](https://hackmd.io/_uploads/rycMrE8Ka.png) 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%20%238-2%20FHIR%20Validation.dib 程式碼深入分析 --- MultiResolver可以包含多個packages,以電子處方簽為例,由於電子處方簽所使用的IG是`https://silcoet.ntunhs.edu.tw/Healthycloud/StructureDefinition-Bundle-EP.html`實際上是繼承tw core ig v0.2.1`https://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與外部服務。