FHIRPath ist die Pfadsprache, mit der FHIR Elemente in Ressourcen auswählt: name.where(use='official').given etwa liefert die Vornamen des offiziellen Namens. Der Tester wertet Ausdrücke direkt auf Ihrem JSON oder XML aus – im Browser, ohne Upload.
Die Daten bleiben in Ihrem Browser: Es wird nichts hochgeladen. Nur zur Ansicht, kein Validator, kein Medizinprodukt.
Wofür FHIRPath in FHIR gebraucht wird
Die Spezifikation nennt FHIRPath (für R4: Release 2) als Pfadsprache für unter anderem Invarianten in ElementDefinition (Regeln für das Zusammenspiel von Elementen), Slicing-Diskriminatoren und Suchparameter. FHIRPath arbeitet auf dem logischen Modell einer Ressource, nicht auf der JSON- oder XML-Syntax. Praktisch heißt das: Derselbe Ausdruck gilt für JSON und XML, und ein Ausdruck liefert immer eine Liste (Collection) von null, einem oder mehreren Werten.
Dieser Tester nutzt evalFhirPath aus @medplum/core (Apache-2.0), das erst beim ersten Auswerten nachgeladen wird. Die Bibliothek ist nachsichtig und nicht identisch mit anderen Implementierungen: Zum Beispiel liefert name.where(use='official')family (Punkt vergessen) kein Fehlersignal, sondern {"use":"official","family":"Chalmers","given":["Peter","Jam…. Verlassen Sie sich für Regelwerke daher nicht allein auf dieses Ergebnis. Der Tester prüft auch nicht, ob ein Pfad für den Ressourcentyp laut Spezifikation existiert.
Fünf Beispiele
Alle Ergebnisse wurden beim Erzeugen dieser Seite mit demselben Code berechnet, den der Tester im Browser nutzt.
1. Ein Element aus einer Liste herausfiltern
name.where(use='official').given.first() auf dem Beispiel „Patient“ ergibt: ["Peter"]
Ein Patient kann mehrere name-Einträge haben, im Beispiel drei (official, usual, maiden). where(use='official') behält den passenden Eintrag, given nimmt dessen Vornamen, first() den ersten.
2. Kontaktdaten nach Verwendung wählen
telecom.where(use='mobile').value auf dem Beispiel „Patient“ ergibt: ["(03) 3410 5613"]
telecom ist eine Liste von Kontaktpunkten. Der Filter auf use liefert die Mobilnummer; ein Eintrag ohne value trägt nichts zum Ergebnis bei.
3. Einen Code aus einem bestimmten Codesystem lesen
code.coding.where(system='http://loinc.org').code auf dem Beispiel „Observation (Körpergewicht)“ ergibt: ["29463-7","3141-9"]
Ein CodeableConcept kann mehrere Codierungen aus verschiedenen Systemen enthalten. Der Filter auf system lässt hier die zwei LOINC-Codes übrig – ein Ergebnis mit zwei Werten, kein einzelner Wert.
4. Werte aus component lesen
component.value.ofType(Quantity).value auf dem Beispiel „Observation (Blutdruck)“ ergibt: [107,60]
Der Blutdruck steht in zwei component-Einträgen. value ist ein Auswahlelement (value[x]); ofType(Quantity) wählt die Variante valueQuantity. Ergebnis: systolisch und diastolisch.
5. Ressourcen in einem Bundle zählen
entry.resource.ofType(Observation).count() auf dem Beispiel „Bundle mit Referenzen“ ergibt: [7]
Bei einem Bundle gilt der Ausdruck für die Wurzel. entry.resource sammelt alle eingebetteten Ressourcen, ofType(Observation) behält die Observations, count() zählt sie. Im Viewer wählen Sie dazu „Ganzes Bundle“.
Stolperstellen
Leere Menge statt Treffer: mehrere Codierungen
component.where(code.coding.code='8480-6').value.ofType(Quantity).value liefert auf dem Blutdruck-Beispiel nichts ([]), obwohl der systolische Wert vorhanden ist. Der code der Komponente hat zwei Codierungen (LOINC und ein lokales System), code.coding.code sind also zwei Werte, und der Vergleich mit = auf einer Liste mit zwei Elementen trifft nicht. Besser: component.where(code.coding.where(code='8480-6').exists()).value.ofType(Quantity).value ergibt [107].
Vergleich mit einer Liste
Ein Patient hat im Beispiel 5 given-Werte über alle Namen. name.given = 'Peter' ergibt [false], weil die ganze Liste mit dem einen Text verglichen wird. name.given.where($this = 'Peter').exists() ergibt [true].
Fehlermeldung „erwartet einen einzelnen Wert“
name.family + ' ' + name.given.first() bricht auf dem Patienten ab, weil name.family zwei Werte liefert (der offizielle und der Mädchenname). Der Tester meldet: „Ein Operand ist eine Liste mit 2 Elementen, erwartet wird ein einzelner Wert. Wählen Sie mit first(), [0] oder where(…) ein Element aus.“ Mit name.first().family + ' ' + name.first().given.first() wählen Sie zuerst einen Namen und erhalten "Chalmers Peter".
XML
Der Ausdruck läuft auf der aus XML umgewandelten Struktur. Ohne Schema erkennt der Viewer Listen nur bei mehrfach vorkommenden Elementen; ein einzelner Eintrag ist dann kein Array. Das kann bei count() oder Indizes zu anderen Ergebnissen führen als bei JSON.