/
ANF XSLT Transformation
ANF XSLT Transformation
Summary
Below highlights a working example of transforming both FHIR Questionnaire Resource and a corresponding Questionnaire Response Resource into a simple notional ANF logical representation. This is achieved utilizing the Saxon XSLT engine (https://www.saxonica.com/documentation/index.html#!using-xsl/commandline) against version 3.0 XSLT and version 3.1 XPath.
Example FHIR Questionnaire Resource
<?xml version="1.0" encoding="UTF-8"?>
<Questionnaire xmlns="http://hl7.org/fhir">
<id value="3141"/>
<text>
<status value="generated"/>
<div xmlns="http://www.w3.org/1999/xhtml">
<pre>1.Comorbidity?
1.1 Cardial Comorbidity
1.1.1 Angina?
1.1.2 MI?
1.2 Vascular Comorbidity?
...
Histopathology
Abdominal
pT category?
...
</pre>
</div>
</text>
<url value="http://hl7.org/fhir/Questionnaire/3141"/>
<title value="Cancer Quality Forum Questionnaire 2012"/>
<status value="draft"/>
<subjectType value="Patient"/>
<date value="2012-01"/>
<item>
<linkId value="1"/>
<code>
<system value="http://example.org/system/code/sections"/>
<code value="COMORBIDITY"/>
</code>
<type value="group"/>
<item>
<linkId value="1.1"/>
<code>
<system value="http://example.org/system/code/questions"/>
<code value="COMORB"/>
</code>
<prefix value="1"/>
<text>Does patient have a Comorbidity?</text>
<type value="choice"/>
<answerValueSet value="http://hl7.org/fhir/ValueSet/yesnodontknow"/>
<item>
<linkId value="1.1.1"/>
<code>
<system value="http://example.org/system/code/sections"/>
<code value="CARDIAL"/>
</code>
<type value="group"/>
<enableWhen>
<question value="1.1"/>
<operator value="="/>
<answerCoding>
<system value="http://terminology.hl7.org/CodeSystem/v2-0136"/>
<code value="Y"/>
</answerCoding>
</enableWhen>
<item>
<linkId value="1.1.1.1"/>
<code>
<system value="http://example.org/system/code/questions"/>
<code value="COMORBCAR"/>
</code>
<prefix value="1.1"/>
<text>Does patient have Cardial Comorbidity?</text>
<type value="choice"/>
<answerValueSet value="http://hl7.org/fhir/ValueSet/yesnodontknow"/>
<item>
<linkId value="1.1.1.1.1"/>
<code>
<system value="http://example.org/system/code/questions"/>
<code value="COMCAR00"/>
<display value="Angina Pectoris"/>
</code>
<code>
<system value="http://snomed.info/sct"/>
<code value="194828000"/>
<display value="Angina (disorder)"/>
</code>
<prefix value="1.1.1"/>
<type value="choice"/>
<answerValueSet value="http://hl7.org/fhir/ValueSet/yesnodontknow"/>
</item>
<item>
<linkId value="1.1.1.1.2"/>
<code>
<system value="http://snomed.info/sct"/>
<code value="22298006"/>
<display value="Myocardial infarction (disorder)"/>
</code>
<prefix value="1.1.2"/>
<type value="choice"/>
<answerValueSet value="http://hl7.org/fhir/ValueSet/yesnodontknow"/>
</item>
</item>
<item>
<linkId value="1.1.1.2"/>
<code>
<system value="http://example.org/system/code/questions"/>
<code value="COMORBVAS"/>
</code>
<prefix value="1.2"/>
<text>Does patient have Vascular Comorbidity?</text>
<type value="choice"/>
<answerValueSet value="http://hl7.org/fhir/ValueSet/yesnodontknow"/>
</item>
</item>
</item>
</item>
<item>
<linkId value="2"/>
<code>
<system value="http://example.org/system/code/sections"/>
<code value="HISTOPATHOLOGY"/>
</code>
<type value="group"/>
<item>
<linkId value="2.1"/>
<code>
<system value="http://example.org/system/code/sections"/>
<code value="ABDOMINAL"/>
</code>
<type value="group"/>
<item>
<linkId value="2.1.2"/>
<code>
<system value="http://example.org/system/code/questions"/>
<code value="STADPT"/>
<display value="pT category"/>
</code>
<type value="choice"/>
</item>
</item>
</item>
</Questionnaire>
Example FHIR Questionnaire Response Resource
<?xml version="1.0" encoding="UTF-8"?>
<QuestionnaireResponse xmlns="http://hl7.org/fhir">
<id value="3141" />
<text>
<status value="generated" />
<div xmlns="http://www.w3.org/1999/xhtml">
<pre>
Comorbidity? YES
Cardial Comorbidity? YES
Angina? YES
MI? NO
Vascular Comorbidity?
(no answers)
...
Histopathology
Abdominal
pT category: 1a
...
</pre>
</div>
</text>
<contained>
<Patient>
<id value="patsub" />
<identifier>
<system value="http://cancer.questionnaire.org/systems/id/patientnr" />
<value value="A34442332" />
</identifier>
<identifier>
<type>
<text value="Dutch BSN" />
</type>
<system value="urn:oid:2.16.840.1.113883.2.4.6.3" />
<value value="188912345" />
</identifier>
<gender value="male" />
<birthDate value="1972-11-30" />
</Patient>
</contained>
<contained>
<ServiceRequest>
<id value="order" />
<status value="unknown" />
<intent value="order" />
<subject>
<reference value="#patsub" />
</subject>
<requester>
<reference value="Practitioner/example" />
</requester>
</ServiceRequest>
</contained>
<contained>
<Practitioner>
<id value="questauth" />
<identifier>
<type>
<text value="AUMC, Den Helder" />
</type>
<system value="http://cancer.questionnaire.org/systems/id/org" />
<value value="AUMC" />
</identifier>
</Practitioner>
</contained>
<!-- TODO: decide how to do this
<contained>
<Observation>
<id value="obs.pt-category"/>
<status value="final"/>
<code>
<coding>
<system value="http://snomed.info/sct"/>
<code value="53786006"/>
<display value="pT1 category"/>
</coding>
</code>
<subject>
<reference value="#patsub"/>
</subject>
<performer>
<reference value="#questauth"/>
</performer>
<valueCodeableConcept>
<coding>
<system value="http://snomed.info/sct"/>
<code value="443357004"/>
<display value="pT1a category"/>
</coding>
</valueCodeableConcept>
</Observation>
</contained> -->
<identifier>
<system value="http://example.org/fhir/NamingSystem/questionnaire-ids" />
<value value="Q12349876" />
</identifier>
<basedOn>
<reference value="#order" />
</basedOn>
<partOf>
<reference value="Procedure/f201" />
</partOf>
<status value="completed" />
<subject>
<reference value="#patsub" />
</subject>
<encounter>
<reference value="Encounter/example" />
</encounter>
<authored value="2013-02-19T14:15:00-05:00" />
<author>
<reference value="#questauth" />
</author>
<item>
<!-- COMORBIDITY -->
<!-- First main section of the form, questions about comorbidity -->
<!-- section contains one question: whether there is comorbidity -->
<linkId value="1" />
<item>
<linkId value="1.1" />
<answer>
<valueCoding>
<system value="http://cancer.questionnaire.org/system/code/yesno" />
<code value="1" />
<display value="Yes" />
</valueCoding>
<item>
<!-- COMORBIDITY/CARDIAL -->
<!-- Subsection about specific comorbidity: cardial -->
<linkId value="1.1.1" />
<item>
<linkId value="1.1.1.1" />
<answer>
<valueCoding>
<system value="http://cancer.questionnaire.org/system/code/yesno" />
<code value="0" />
</valueCoding>
</answer>
</item>
<item>
<!-- This answer carries both the questionnaire-specific name and an equivalent SNOMED
CT code -->
<linkId value="1.1.1.2" />
<answer>
<valueCoding>
<system value="http://cancer.questionnaire.org/system/code/yesno" />
<code value="3" />
</valueCoding>
</answer>
</item>
<item>
<linkId value="1.1.1.3" />
<answer>
<valueCoding>
<system value="http://cancer.questionnaire.org/system/code/yesno" />
<code value="0" />
</valueCoding>
</answer>
</item>
</item>
</answer>
</item>
</item>
<!-- HISTOPATHOLOGY -->
<!-- TODO: decide how to do this
<item>
<item>
<item>
<dataResource>
<reference value="#obs.pt-category"/>
</dataResource>
</item>
</item>
</item> -->
</QuestionnaireResponse>
Notional Logical ANF XSTL Transformation
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xpath-default-namespace="http://hl7.org/fhir">
<xsl:output indent="yes" omit-xml-declaration="no"/>
<xsl:variable name="presentRange">(0,INF)</xsl:variable>
<xsl:variable name="absentRange">[0,0]</xsl:variable>
<xsl:variable name="indeterminateRange">[0,INF)</xsl:variable>
<xsl:template match="/">
<anf>
<xsl:for-each select="//item">
<xsl:if test="./type/@value = 'choice'">
<xsl:variable name="questionId" select="./linkId/@value"/>
<xsl:variable name="questionTopic" select="./code/code/@value"/>
<xsl:variable name="questionNarrative" select="./text"/>
<xsl:for-each select="document('questionnaireResponse.xml')//item">
<xsl:if test="./linkId/@value = $questionId">
<statement>
<narrative>
<xsl:value-of select="$questionNarrative"/>
</narrative>
<topic>
<xsl:value-of select="$questionTopic"/>
</topic>
<circumstance type="performance">
<status>Complete</status>
<result>
<xsl:choose>
<xsl:when test="./answer/valueCoding/code/@value = 1">
<xsl:value-of select="$presentRange"/>
</xsl:when>
<xsl:when test="./answer/valueCoding/code/@value = 0">
<xsl:value-of select="$absentRange"/>
</xsl:when>
<xsl:when test="./answer/valueCoding/code/@value = 3">
<xsl:value-of select="$indeterminateRange"/>
</xsl:when>
</xsl:choose>
</result>
</circumstance>
</statement>
</xsl:if>
</xsl:for-each>
</xsl:if>
</xsl:for-each>
</anf>
</xsl:template>
</xsl:stylesheet>
Notional Logical ANF Output
<?xml version="1.0" encoding="UTF-8"?>
<anf>
<statement>
<narrative>Does patient have a Comorbidity?</narrative>
<topic>COMORB</topic>
<circumstance type="performance">
<status>Complete</status>
<result>(0,INF)</result>
</circumstance>
</statement>
<statement>
<narrative>Does patient have Cardial Comorbidity?</narrative>
<topic>COMORBCAR</topic>
<circumstance type="performance">
<status>Complete</status>
<result>[0,0]</result>
</circumstance>
</statement>
<statement>
<narrative>Does patient have Vascular Comorbidity?</narrative>
<topic>COMORBVAS</topic>
<circumstance type="performance">
<status>Complete</status>
<result>[0,INF)</result>
</circumstance>
</statement>
</anf>
Related content
Does the patient have chronic liver disease?
Does the patient have chronic liver disease?
More like this
Does the patient currently have Chronic Renal Disease?
Does the patient currently have Chronic Renal Disease?
More like this
Does the patient have Cardiovascular disease? - in progress
Does the patient have Cardiovascular disease? - in progress
More like this
Does patient have a history of Diabetes?
Does patient have a history of Diabetes?
More like this
What is the patients current smoking status?- in progress
What is the patients current smoking status?- in progress
More like this
Does the patient have an immunosuppressive condition?
Does the patient have an immunosuppressive condition?
More like this