<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:b="urn:hl7-org:v2xml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
	<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
	<xsl:template match="/">
		<clinicaldata:ClinicalData xmlns:clinicaldata="Clinicaldata">
			<templateId>LabCreateOrUpdate40060</templateId>
			<patient>

				<xsl:variable name="nationalId" select="b:ORU_R01/b:ORU_R01.PATIENT_RESULT/b:ORU_R01.PATIENT/b:PID/b:PID.3[b:CX.5 = 'NI'][1]/b:CX.1"/>
				<xsl:if test="string-length($nationalId) > 0">
					<requestedNationalId>
						<xsl:value-of select="$nationalId"/>
					</requestedNationalId>
				</xsl:if>

				<xsl:for-each select="b:ORU_R01/b:ORU_R01.PATIENT_RESULT">
					<labTestPromises>
						<!-- The ORC and OBR may repeat (for panels or panels of panels) but represent the same LabTestPromise -->
						<!-- We need to initially ignore the repeats of ORC and OBR and only look at the first grouping ([1]) -->
						<!-- Later need to look at each repeating group to select information for individual lab tests -->
						<xsl:variable name="firstGroupingORC" select="b:ORU_R01.ORDER_OBSERVATION[1]/b:ORC"/>
						<xsl:variable name="firstGroupingOBR" select="b:ORU_R01.ORDER_OBSERVATION[1]/b:OBR"/>
						<xsl:variable name="firstGroupingNTE" select="b:ORU_R01.ORDER_OBSERVATION[1]"/>
						<xsl:if test="(($firstGroupingORC/b:ORC.3/b:EI.1 != '') and ($firstGroupingORC/b:ORC.3/b:EI.2 != ''))">
							<recordIdentifier>
								<xsl:call-template name="getIdentifier">
									<xsl:with-param name="theIdentifier" select="$firstGroupingORC/b:ORC.3"/>
								</xsl:call-template>
							</recordIdentifier>
						</xsl:if>
						<xsl:for-each select="b:ORU_R01.PATIENT/b:PID/b:PID.3[b:CX.5 = 'PI']">
							<xsl:call-template name="getPatientLite"/>
						</xsl:for-each>
						<placerOrderIdentifier>
							<xsl:call-template name="getIdentifier">
								<xsl:with-param name="theIdentifier" select="$firstGroupingORC/b:ORC.2"/>
							</xsl:call-template>
						</placerOrderIdentifier>
						<placerAccessionReference>
							<xsl:value-of select="$firstGroupingOBR/b:OBR.19"/>
						</placerAccessionReference>
						<fillerIenReference>
							<xsl:value-of select="$firstGroupingOBR/b:OBR.20"/>
						</fillerIenReference>
						<reportCompleteDate>
							<literal>
								<xsl:value-of select="$firstGroupingOBR/b:OBR.22"/>
							</literal>
						</reportCompleteDate>
						<labSubscript>
							<xsl:value-of select="$firstGroupingOBR/b:OBR.24"/>
						</labSubscript>
						<priority>
							<xsl:value-of select="$firstGroupingORC/b:ORC.7/b:TQ.6"/>
						</priority>
						<status>
							<xsl:value-of select="$firstGroupingOBR/b:OBR.25"/>
						</status>
						<xsl:for-each select="$firstGroupingNTE/b:NTE[b:NTE.4/b:CE.1]">
							<labCommentEvents>
								<xsl:call-template name="getComments"/>
							</labCommentEvents>
						</xsl:for-each>
						<labTestRequest>
							<author>
								<xsl:call-template name="getPractitioner">
									<xsl:with-param name="thePractitioner" select="$firstGroupingORC/b:ORC.12"/>
								</xsl:call-template>
							</author>
							<requestingLocationIdentifier>
								<xsl:call-template name="getLocationIdentifier">
									<xsl:with-param name="theLocation" select="$firstGroupingORC/b:ORC.13"/>
								</xsl:call-template>
							</requestingLocationIdentifier>
							<requestingOrganization>
								<xsl:call-template name="getCodedElementLite">
									<xsl:with-param name="theCode" select="$firstGroupingORC/b:ORC.17"/>
								</xsl:call-template>
							</requestingOrganization>
							<orderingFacilityIdentifier>
								<xsl:call-template name="getOrganizationIdentifierExtended">
									<xsl:with-param name="theOrganization" select="$firstGroupingORC/b:ORC.21"/>
								</xsl:call-template>
							</orderingFacilityIdentifier>
							<orderingFacilityAddress>
								<xsl:call-template name="getAddress">
									<xsl:with-param name="theAddress" select="$firstGroupingORC/b:ORC.22"/>
								</xsl:call-template>
							</orderingFacilityAddress>
						</labTestRequest>
						<patientVisit>
							<xsl:variable name="patientVisit" select="b:ORU_R01.PATIENT/b:PV1"/>
							<patientClass>
								<xsl:value-of select="$patientVisit/b:PV1.2"/>
							</patientClass>
							<assignedLocation>
								<xsl:call-template name="getLocationIdentifier">
									<xsl:with-param name="theLocation" select="$patientVisit/b:PV1.3"/>
								</xsl:call-template>
							</assignedLocation>
							<priorLocation>
								<xsl:call-template name="getLocationIdentifier">
									<xsl:with-param name="theLocation" select="$patientVisit/b:PV1.6"/>
								</xsl:call-template>
							</priorLocation>
							<attendingDoctor>
								<xsl:call-template name="getPractitioner">
									<xsl:with-param name="thePractitioner" select="$patientVisit/b:PV1.7"/>
								</xsl:call-template>
							</attendingDoctor>
							<hospitalService>
								<xsl:value-of select="$patientVisit/b:PV1.10"/>
							</hospitalService>
							<patientType>
								<xsl:value-of select="$patientVisit/b:PV1.18"/>
							</patientType>
							<chargePriceIndicator>
								<xsl:value-of select="$patientVisit/b:PV1.21"/>
							</chargePriceIndicator>
							<dischargeDisposition>
								<xsl:value-of select="$patientVisit/b:PV1.36"/>
							</dischargeDisposition>
							<servicingFacility>
								<xsl:value-of select="$patientVisit/b:PV1.39"/>
							</servicingFacility>
							<admissionDate>
								<literal>
									<xsl:value-of select="$patientVisit/b:PV1.44/b:TS.1"/>
								</literal>
							</admissionDate>
							<alternateVisitId>
								<xsl:value-of select="$patientVisit/b:PV1.50/b:CX.1"/>
							</alternateVisitId>
						</patientVisit>
						<specimen>
							<specimenSource>
								<xsl:call-template name="getCodedElementExtended">
									<xsl:with-param name="theCode" select="$firstGroupingOBR/b:OBR.15/b:SPS.1"/>
								</xsl:call-template>
							</specimenSource>
							<xsl:if test="($firstGroupingOBR/b:OBR.7/b:TS.1 != '') ">
								<specimenTakenDate>
									<literal>
										<xsl:value-of select="$firstGroupingOBR/b:OBR.7/b:TS.1"/>
									</literal>
								</specimenTakenDate>
							</xsl:if>
							<specimenReceivedDate>
								<literal>
									<xsl:value-of select="$firstGroupingOBR/b:OBR.14/b:TS.1"/>
								</literal>
							</specimenReceivedDate>
							<specimenAction>
								<xsl:value-of select="$firstGroupingOBR/b:OBR.11"/>
							</specimenAction>
						</specimen>
						<!-- from here we need to start looking at each repeating ORC OBR Group -->
						<!-- these repeats represent unique LabTests -->
						<xsl:for-each select="b:ORU_R01.ORDER_OBSERVATION">
							<labTests>
								<procedureCode>
									<xsl:call-template name="getCodedElement">
										<xsl:with-param name="theCode" select="b:OBR/b:OBR.44"/>
									</xsl:call-template>
								</procedureCode>
								<orderedTestCode>
									<xsl:call-template name="getCodedElement">
										<xsl:with-param name="theCode" select="b:OBR/b:OBR.4"/>
									</xsl:call-template>
								</orderedTestCode>
								<fillerAccessionReference>
									<xsl:value-of select="b:OBR/b:OBR.21"/>
								</fillerAccessionReference>
								<!-- from here we start getting multiple chemistry results for each Lab Test -->
								<xsl:for-each select="b:ORU_R01.OBSERVATION">
									<chemistryResults>
										<valueInterpretation>
											<xsl:value-of select="b:OBX/b:OBX.8"/>
										</valueInterpretation>
										<observationDate>
											<literal>
												<xsl:value-of select="b:OBX/b:OBX.14"/>
											</literal>
										</observationDate>
										<observationStatus>
											<xsl:value-of select="b:OBX/b:OBX.11"/>
										</observationStatus>
										<testIdentifier>
											<xsl:call-template name="getCodedElementExtended">
												<xsl:with-param name="theCode" select="b:OBX/b:OBX.3"/>
											</xsl:call-template>
										</testIdentifier>
										<referenceRange>
											<xsl:value-of select="b:OBX/b:OBX.7"/>
										</referenceRange>
										<xsl:for-each select="b:NTE[b:NTE.4/b:CE.1]">
											<labCommentEvents>
												<xsl:call-template name="getComments"/>
											</labCommentEvents>
										</xsl:for-each>
										<observationValue>
											<xsl:value-of select="b:OBX/b:OBX.5"/>
										</observationValue>
										<observationUnits>
											<xsl:call-template name="getCodedElementLite">
												<xsl:with-param name="theCode" select="b:OBX/b:OBX.6"/>
											</xsl:call-template>
										</observationUnits>
										<deviceIdentifier>
											<xsl:call-template name="getIdentifier">
												<xsl:with-param name="theIdentifier" select="b:OBX/b:OBX.18"/>
											</xsl:call-template>
										</deviceIdentifier>
										<observationValueType>
											<xsl:value-of select="b:OBX/b:OBX.2"/>
										</observationValueType>
										<producerCode>
											<xsl:call-template name="getCodedElement">
												<xsl:with-param name="theCode" select="b:OBX/b:OBX.15"/>
											</xsl:call-template>
										</producerCode>
										<verifier>
											<xsl:call-template name="getPractitioner">
												<xsl:with-param name="thePractitioner" select="b:OBX/b:OBX.16"/>
											</xsl:call-template>
										</verifier>
										<analysisDate>
											<literal>
												<xsl:value-of select="b:OBX/b:OBX.19/b:TS.1"/>
											</literal>
										</analysisDate>
										<performingOrganization>
											<identifier>
												<xsl:call-template name="getOrganizationIdentifierExtended">
													<xsl:with-param name="theOrganization" select="b:OBX/b:OBX.23"/>
												</xsl:call-template>
											</identifier>
											<address>
												<xsl:call-template name="getAddress">
												<xsl:with-param name="theAddress" select="b:OBX/b:OBX.24"/>
											</xsl:call-template>
											</address>
											<medicalDirector>
												<xsl:call-template name="getPractitionerName">
													<xsl:with-param name="thePractitioner" select="b:OBX/b:OBX.25"/>
												</xsl:call-template>
											</medicalDirector>
										</performingOrganization>
										<xsl:for-each select="b:OBX/b:OBX.17">
											<observationMethods>
												<observationMethodCode>
													<xsl:call-template name="getCodedElement">
														<xsl:with-param name="theCode" select="."/>
													</xsl:call-template>
												</observationMethodCode>
											</observationMethods>
										</xsl:for-each>
									</chemistryResults>
								</xsl:for-each>
							</labTests>
						</xsl:for-each>
						<xsl:for-each select="../b:MSH">
							<xsl:call-template name="getRecordInformation"/>
						</xsl:for-each>
					</labTestPromises>
				</xsl:for-each>
			</patient>
		</clinicaldata:ClinicalData>
	</xsl:template>
	<!--
		######################################################
		################# COMMON TEMPLATES #################
		
		getIdentifier template
		applies to any path ending in EI 
		
	-->
	<xsl:template name="getIdentifier">
		<xsl:param name="theIdentifier"/>
		<identity>
			<xsl:value-of select="$theIdentifier/b:EI.1"/>
		</identity>
		<namespaceId>
			<xsl:value-of select="$theIdentifier/b:EI.2"/>
		</namespaceId>
		<universalId>
			<xsl:value-of select="$theIdentifier/b:EI.3"/>
		</universalId>
		<universalIdType>
			<xsl:value-of select="$theIdentifier/b:EI.4"/>
		</universalIdType>
	</xsl:template>
	<!--
		###################################################
		
		getPatientLite template
		applies to PID/b:PID.3[b:CX.5 = 'PI'] path 
		
	-->
	<xsl:template name="getPatientLite">
		<xsl:if test="((b:CX.1 != '') and (b:CX.6/b:HD.2 != '') and (b:CX.4/b:HD.1 != ''))">
			<patient>
				<identifier>
					<identity>
						<xsl:value-of select="b:CX.1"/>
					</identity>
					<assigningFacility>
						<xsl:value-of select="b:CX.6/b:HD.2"/>
					</assigningFacility>
					<assigningAuthority>
						<xsl:value-of select="b:CX.4/b:HD.1"/>
					</assigningAuthority>
				</identifier>
				<!-- get  'L' (legal) name of this patient when possible otherwise take the first occurrence-->
				<xsl:choose>
					<xsl:when test="../b:PID.5[b:XPN.7 = 'L']">
						<name>
							<prefix>
								<xsl:value-of select="../b:PID.5[b:XPN.7 = 'L']/b:XPN.5"/>
							</prefix>
							<given>
								<xsl:value-of select="../b:PID.5[b:XPN.7 = 'L']/b:XPN.2"/>
							</given>
							<middle>
								<xsl:value-of select="../b:PID.5[b:XPN.7 = 'L']/b:XPN.3"/>
							</middle>
							<family>
								<xsl:value-of select="../b:PID.5[b:XPN.7 = 'L']/b:XPN.1/b:FN.1"/>
							</family>
							<suffix>
								<xsl:value-of select="../b:PID.5[b:XPN.7 = 'L']/b:XPN.4"/>
							</suffix>
							<title>
								<xsl:value-of select="../b:PID.5[b:XPN.7 = 'L']/b:XPN.6"/>
							</title>
						</name>
					</xsl:when>
					<xsl:otherwise>
						<xsl:if test="../b:PID.5[1]/b:XPN.1/b:FN.1">
							<name>
								<prefix>
									<xsl:value-of select="../b:PID.5[1]/b:XPN.5"/>
								</prefix>
								<given>
									<xsl:value-of select="../b:PID.5[1]/b:XPN.2"/>
								</given>
								<middle>
									<xsl:value-of select="../b:PID.5[1]/b:XPN.3"/>
								</middle>
								<family>
									<xsl:value-of select="../b:PID.5[1]/b:XPN.1/b:FN.1"/>
								</family>
								<suffix>
									<xsl:value-of select="../b:PID.5[1]/b:XPN.4"/>
								</suffix>
								<title>
									<xsl:value-of select="../b:PID.5[1]/b:XPN.6"/>
								</title>
							</name>
						</xsl:if>
					</xsl:otherwise>
				</xsl:choose>
			</patient>
		</xsl:if>
	</xsl:template>
	<!--
		#####################################################
		
		getRecordInformation template
		applies to MSH path 
		
	-->
	<xsl:template name="getRecordInformation">
		<xsl:if test="(b:MSH.4/b:HD.1 != '')">
			<recordSource>
				<namespaceId>
					<xsl:value-of select="b:MSH.4/b:HD.1"/>
				</namespaceId>
				<universalId>
					<xsl:value-of select="b:MSH.4/b:HD.2"/>
				</universalId>
				<universalIdType>
					<xsl:value-of select="b:MSH.4/b:HD.3"/>
				</universalIdType>
			</recordSource>
		</xsl:if>
		<recordVersion>0</recordVersion>
		<xsl:if test="(b:MSH.7/b:TS.1 != '')">
			<recordUpdateTime>
				<literal>
					<xsl:value-of select="b:MSH.7/b:TS.1"/>
				</literal>
			</recordUpdateTime>
		</xsl:if>
	</xsl:template>
	<!--
		#########################################################
		
		getCodedElementExtended template 
		applies to any path ending in CNE or CWE and transforming all 9 components
		
	-->
	<xsl:template name="getCodedElementExtended">
		<xsl:param name="theCode"/>
		<code>
			<xsl:value-of select="$theCode/(b:CNE.1 | b:CWE.1)"/>
		</code>
		<displayText>
			<xsl:value-of select="$theCode/(b:CNE.2 | b:CWE.2)"/>
		</displayText>
		<codingSystem>
			<xsl:value-of select="$theCode/(b:CNE.3 | b:CWE.3)"/>
		</codingSystem>
		<codingSystemVersion>
			<xsl:value-of select="$theCode/(b:CNE.7 | b:CWE.7)"/>
		</codingSystemVersion>
		<alternateCode>
			<xsl:value-of select="$theCode/(b:CNE.4 | b:CWE.4)"/>
		</alternateCode>
		<alternateDisplayText>
			<xsl:value-of select="$theCode/(b:CNE.5 | b:CWE.5)"/>
		</alternateDisplayText>
		<alternateCodingSystem>
			<xsl:value-of select="$theCode/(b:CNE.6 | b:CWE.6)"/>
		</alternateCodingSystem>
		<alternateCodingSystemVersion>
			<xsl:value-of select="$theCode/(b:CNE.8 | b:CWE.8)"/>
		</alternateCodingSystemVersion>
		<originalText>
			<xsl:value-of select="$theCode/(b:CNE.9 | b:CWE.9)"/>
		</originalText>
	</xsl:template>
	<!--
		#########################################################
		
		getCodedElement template 
		applies to any path ending in CE and transforming all 6 components
        first call 'getCodedElementLite for the first 3 components
		then fill the remaining 3 'alternate' components
		
	-->
	<xsl:template name="getCodedElement">
		<xsl:param name="theCode"/>
		<xsl:call-template name="getCodedElementLite">
			<xsl:with-param name="theCode" select="$theCode"/>
		</xsl:call-template>
		<alternateCode>
			<xsl:value-of select="$theCode/(b:CE.4 | b:CNE.4)"/>
		</alternateCode>
		<alternateDisplayText>
			<xsl:value-of select="$theCode/(b:CE.5 | b:CNE.5)"/>
		</alternateDisplayText>
		<alternateCodingSystem>
			<xsl:value-of select="$theCode/(b:CE.6 | b:CNE.6)"/>
		</alternateCodingSystem>
	</xsl:template>
	<!--
		#########################################################
		
		getCodedElementLite template 
		applies to any path ending in CE or CNE and transforming CE.1/CNE.1, CE.2/CNE.2, and CE.3/CNE.3 into code, displayText, and codingSystem respectively
		
	-->
	<xsl:template name="getCodedElementLite">
		<xsl:param name="theCode"/>
		<code>
			<xsl:value-of select="$theCode/(b:CE.1 | b:CNE.1)"/>
		</code>
		<displayText>
			<xsl:value-of select="$theCode/(b:CE.2 | b:CNE.2)"/>
		</displayText>
		<codingSystem>
			<xsl:value-of select="$theCode/(b:CE.3 | b:CNE.3)"/>
		</codingSystem>
	</xsl:template>
	<!--
		#####################################################
		
		getComments template
		applies to NTE path 
		
	-->
	<xsl:template name="getComments">
		<commentTypeCode>
			<xsl:call-template name="getCodedElementLite">
				<xsl:with-param name="theCode" select="b:NTE.4"/>
			</xsl:call-template>
		</commentTypeCode>
		<xsl:for-each select="b:NTE.3">
			<comments>
				<xsl:value-of select="."/>
			</comments>
		</xsl:for-each>
	</xsl:template>
	<!--
		######################################################
		
		getPractitioner template 
		applies to XCN transforming XCN.1 through XCN.8 into the appropriate Pracitioner elements
		
	-->
	<xsl:template name="getPractitioner">
		<xsl:param name="thePractitioner"/>
		<identifier>
			<identity>
				<xsl:value-of select="$thePractitioner/b:XCN.1"/>
			</identity>
			<assigningFacility/>
			<assigningAuthority>
				<xsl:value-of select="$thePractitioner/b:XCN.9/b:HD.1"/>
			</assigningAuthority>
		</identifier>
		<idSourceTable>
			<xsl:value-of select="$thePractitioner/b:XCN.8"/>
		</idSourceTable>
		<name>
			<xsl:call-template name="getPractitionerName">
				<xsl:with-param name="thePractitioner" select="$thePractitioner"/>
			</xsl:call-template>
		</name>
	</xsl:template>
	<!--
		######################################################
		
		getPractitionerName template 
		applies to XCN 
		
	-->
	<xsl:template name="getPractitionerName">
		<xsl:param name="thePractitioner"/>
		<prefix>
			<xsl:value-of select="$thePractitioner/b:XCN.6"/>
		</prefix>
		<given>
			<xsl:value-of select="$thePractitioner/b:XCN.3"/>
		</given>
		<middle>
			<xsl:value-of select="$thePractitioner/b:XCN.4"/>
		</middle>
		<family>
			<xsl:value-of select="$thePractitioner/b:XCN.2/b:FN.1"/>
		</family>
		<suffix>
			<xsl:value-of select="$thePractitioner/b:XCN.5"/>
		</suffix>
		<title>
			<xsl:value-of select="$thePractitioner/b:XCN.7"/>
		</title>
	</xsl:template>
	<!--
		######################################################
		getOrganizationIdentifierExtended template
		applies to any path ending in XON
		
	-->
	<xsl:template name="getOrganizationIdentifierExtended">
		<xsl:param name="theOrganization"/>
		<identity>
			<xsl:value-of select="$theOrganization/b:XON.10"/>
		</identity>
		<name>
			<xsl:value-of select="$theOrganization/b:XON.1"/>
		</name>
		<assigningAuthority>
			<xsl:value-of select="$theOrganization/b:XON.6/b:HD.1"/>
		</assigningAuthority>
		<nameTypeCode>
			<xsl:value-of select="$theOrganization/b:XON.2"/>
		</nameTypeCode>
		<identityTypeCode>
			<xsl:value-of select="$theOrganization/b:XON.7"/>
		</identityTypeCode>
		<nameRepresentation>
			<xsl:value-of select="$theOrganization/b:XON.9"/>
		</nameRepresentation>
		<stationNumber>
			<xsl:value-of select="$theOrganization/b:XON.3"/>
		</stationNumber>
	</xsl:template>
	<!--
		##########################
		getAddress template
		applies to any path ending in XAD
		
	-->
	<xsl:template name="getAddress">
		<xsl:param name="theAddress"/>
		<line1>
			<xsl:value-of select="$theAddress/b:XAD.1/b:SAD.1"/>
		</line1>
		<line2>
			<xsl:value-of select="$theAddress/b:XAD.2"/>
		</line2>
		<city>
			<xsl:value-of select="$theAddress/b:XAD.3"/>
		</city>
		<postalCode>
			<xsl:value-of select="$theAddress/b:XAD.5"/>
		</postalCode>
		<country>
			<xsl:value-of select="$theAddress/b:XAD.6"/>
		</country>
		<state>
			<xsl:value-of select="$theAddress/b:XAD.4"/>
		</state>
	</xsl:template>
	<!--
		######################################################
		
		getLocationIdentifier template 
		applies to PL 
		
	-->
	<xsl:template name="getLocationIdentifier">
		<xsl:param name="theLocation"/>
		<pointOfCare>
			<xsl:value-of select="$theLocation/b:PL.1"/>
		</pointOfCare>
		<room>
			<xsl:value-of select="$theLocation/b:PL.2"/>
		</room>
		<bed>
			<xsl:value-of select="$theLocation/b:PL.3"/>
		</bed>
		<facilityNamespaceId>
			<xsl:value-of select="$theLocation/b:PL.4/b:HD.1"/>
		</facilityNamespaceId>
		<facilityUniversalId>
			<xsl:value-of select="$theLocation/b:PL.4/b:HD.2"/>
		</facilityUniversalId>
		<facilityUniversalIdType>
			<xsl:value-of select="$theLocation/b:PL.4/b:HD.3"/>
		</facilityUniversalIdType>
		<personLocationType>
			<xsl:value-of select="$theLocation/b:PL.6"/>
		</personLocationType>
		<locationDescription>
			<xsl:value-of select="$theLocation/b:PL.9"/>
		</locationDescription>
	</xsl:template>
</xsl:stylesheet>
