Purpose: provide a mapping for QUPC_IN990002NL to one of QUPC_IN443230NL, QUPC_IN443231NL, QUPC_IN443232NL, and for one of QUPC_IN443130NL, QUPC_IN443131NL, QUPC_IN443132NL to QUPC_IN990001NL
Prerequisites:
any XSLT 2.0 capable transformation engine. Tested with Saxon 9.1.0.5, Saxon-HE 9.3.0.5
and Saxon-EE 9.3.0.5
XML Schema valid instance of interaction QUPC_IN443130NL, or
XML Schema valid instance of interaction QUPC_IN443131NL, or
XML Schema valid instance of interaction QUPC_IN443132NL, or
XML Schema valid instance of interaction QUPC_IN990002NL, or
XML Schema valid instance of interaction MCCI_IN200101 containing no interactions,
or XML Schema valid instances of QUPC_IN990002NL
Underlying specification: AORTA_7PriCa_Mapping_CP_HAZ.xls version 1.0
The output document contains a one of several types of CareProvisions or a PS-query.
Each one needs a (slightly) different mapping. It is left up to the caller of this
transformation
to tell us through the parameter 'g_outputInteractionId' which output document is expected.
Specific filtering is applied on what gets transformed into the output based on the
output interactionId. The filtering works as follows:
Opvragen Professionele samenvatting. g_outputInteractionId = ignored, but mandatory
No specific filtering, but only the parameter patientId can be transformed into the
output
EpisodeOfCondition - Open episodes - Get PrimaryCareProvision/component7/EpisodeOfCondition[not(statusCode='completed'
or effectiveTime/high)]
Contact - Datum contact t/m 10 dg geleden - Get PrimaryCareProvision/component1/encounter[$today-effectiveTime/low/@value
<= 10000000]
Journaalregel - Behorend bij de geselecteerde contacten - Get every JournalEntry under
copied encounter
Diagnose - Behorend bij de geselecteerde contacten - Get every ObservationDx under
copied encounter
Uitslag (meting, bepaling) - Datum meting t/m 10 dg geleden - Get PrimaryCareProvision/component2/observation[$today-effectiveTime/low/@value
<= 10000000]
Overdrachtgegevens - Alles - Get PrimaryCareProvision, PrimaryCareProvision/pertinentInformation
Correspondentie - Datum brief t/m 10 dg geleden - not possible
Belaste familieanamnese - Alles - not possible
Ook bekend bij - not permitted
History:
2012-09-19 AH - version 0.8.7
Overall: merge of CSC version 0.8.5 with Nictiz version 0.8.6. Purpose is not to have
a disjunct between the versions anymore. However since CSC currently uses XSL 1.0
and this is XSL 2.0 differences still exist
Change: output will not have an XML declaration anymore (omit-xml-declaration="yes")
Change: all references to XML Schema and Schematron have been removed. These don't
belong in production. These were for debugging purposes and had no message impact
Change: added REQUIRED parameter g_tsToday that MUST hold the current date/time as YYYYMMddhhmmss. This circumvents the need
to call date functions for getting todays date as this is not supported in Xalan-C.
2012-06-05 AH - version 0.8.6
Change: copy ObservationIntolerance/statusCode only if it has @code. A number of examples
were found without @code
Change: copy [episodeOfCondition|ContraIndication|ObservationIntolerance|observation]/text
only if it has text(). A number of examples were found without content
Change: copy [annotation|episodeOfCondition|ContraIndication|ObservationIntolerance|observation|ObservationDx]/effectiveTime
only if it has content (.//@nullFlavor or .//@value). A number of examples were found
without content
2012-06-04 AH/GM - version 0.8.5
Change: added transformation of ContraIndication and ObservationIntolerance
Bugfix: attributes on ObservationDx where copied in context of ObservationDx/code
2012-05-31 AH - version 0.8.1
Change: fixed all FIXMEs and TODOs with regards to transformation. This led to one
change in the handling of EpisodeOfCondition. EpisodeOfCondition/text is now mapped
as well
Change: xsi:types are now patched in a more secure fashion. Always first copy all
attributes, then write xsi:type explicitly
Change: xsl:attributes are now called in an XSL 1.0 compatible way
2012-04-24 AH - version 0.7.1
Second round of steep testing based on 218 XML Schema valid, qualification test messages.
All changes were based on variations found in those. This round the filtering was
removed so (almost all data was copied giving much more to test against)
Bugfix: QUPC_IN990002NL, component2 Activities were always copied instead of based on effectiveTime due to
an incorrect XPath
Change: QUPC_IN990002NL, added traceability comments on component2 Activities to see which were skipped
Change: Encounter, most common input errors in Encounter.code are now fixed in the transformation,
see new template EncounterCode for details
Change: Encounter, most common input errors in Encounter.effectiveTime are now fixed in the transformation,
see effectiveTime for details
Change: ActReference, qualification testing on the input has not been very strong, so we need to distrust
whatever is present in @classCode/@moodCode and determine that ourselves based on
the object the ActReference refers to
Change: observation, added fixme on observation.id. Most input doesn't have this, but output requires
it. Suggestion: fix output spec to allow null
Change: effectiveTime, now also fixes equal low/high with date+hour and date+hour+minute
Change: extended, rearranged documentation
2012-04-24 AH - version 0.7
Steep testing based on 218 XML Schema valid, qualification test messages. Most changes
were based on variations found in those. Filtering was active.
Bugfix: QUPC_IN990002NL, added support for ControlActProcess/reason, and made ControlActProcess/subject optional
Bugfix: PrimaryCareProvision, switched order of PrimaryCareProvision/author, and PrimaryCareProvision/perfomer
Bugfix: PrimaryCareProvision, only copy episodeOfCondition if it has a diagnosis with at least a code and effectiveTime
to avoid XML Schema problem in output
Bugfix: R_AssignedEntityUniversal if contents of a supposedly Universal element is Identified after all, use appropriate
templateId
Bugfix: ObservationDx Some vendors took our older examples literally and forgot @codeSystem in ObservationDx/code.
Fixed that input mistake for output.
Bugfix: ObservationDx Changed author mapping to go to AssignedEntity instead of AssignedPerson.
Removed support for Activities/act since it was not in the PS-spec yet and so no testing
was possible
Only copy JournalEntry and ObservationDx when available via component2 (not in scope
of an encounter) and less than 10 days old
New: effectiveTime, created separate template to fix certain variations of low==high
2012-04-22 AH - version 0.6.5
Added support to transforming the query interactions QUPC_IN443130NL, QUPC_IN443131NL,
QUPC_IN443132NL to QUPC_IN990001NL.
2012-04-22 AH - version 0.6
Implemented first version of filtering. Feature complete except for questions around
CareStatement/act and what to do with component2/*. Filter just filters component1/encounter
Fixed and simplified AssignedEntity/AssignedPerson support
Fixed actReference support
Extended documentation, but not finished
Added rudimentary traceability information to let you know where a certain piece of
info came from
2012-04-20 AH - version 0.5.2
Extended documentation
2012-04-18 AH - version 0.5.1
Added minimal disclaimer with reference to LGPL and copyright
2012-04-18 AH - version 0.5
Initial version. Tested with all available example files in xml-WDH
Known issue - filters per output document not implemented yet
Disclaimer:
This program is free software; you can redistribute it and/or modify it under the
terms of the
GNU Lesser General Public License as published by the Free Software Foundation; either
version
2.1 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
The full text of the license is available at http://www.gnu.org/copyleft/lesser.html
<xsl:template match="/"><!-- Check parameter values --><xsl:call-template name="sanityCheck"/><xsl:comment>Converted from<xsl:value-of select="local-name(hl7:*)"/>by PrimaryCareProvision2CareProvision.xsl<xsl:value-of select="$g_version"/>at<xsl:value-of select="$logDate"/></xsl:comment><xsl:choose><!-- TODO: find out if support for batches is needed at all. Added support for convenience here --><xsl:when test="/hl7:MCCI_IN200101[hl7:QUPC_IN990002NL or not(following-sibling::hl7:sender)]"><xsl:message>[info] Supported interaction. Found '<xsl:value-of select="name(*[1])"/>', transforming into '<xsl:value-of select="name(*[1])"/>' with date string '<xsl:value-of select="$tsToday"/>'</xsl:message><xsl:apply-templates select="/hl7:MCCI_IN200101"/></xsl:when><xsl:when test="/hl7:QUPC_IN990002NL"><xsl:message>[info] Supported interaction. Found '<xsl:value-of select="name(*[1])"/>', transforming into '<xsl:value-of select="$g_outputInteractionId"/>' with date string '<xsl:value-of select="$tsToday"/>'</xsl:message><xsl:apply-templates select="/hl7:QUPC_IN990002NL"/></xsl:when><xsl:when test="/hl7:QUPC_IN443130NL | /hl7:QUPC_IN443131NL | /hl7:QUPC_IN443132NL"><xsl:message>[info] Supported interaction. Found '<xsl:value-of select="name(*[1])"/>', transforming into 'QUPC_IN990001NL' with date string '<xsl:value-of select="$tsToday"/>'</xsl:message><xsl:apply-templates select="/hl7:QUPC_IN443130NL | /hl7:QUPC_IN443131NL | /hl7:QUPC_IN443132NL"/></xsl:when><xsl:otherwise><xsl:message terminate="yes">[error] Unsupported interaction. Found '<xsl:value-of select="name(*[1])"/>', but need 'MCCI_IN200101' containing 'QUPC_IN990002NL', or plain 'QUPC_IN990002NL', or one of 'QUPC_IN443130NL', 'QUPC_IN443131NL', 'QUPC_IN443132NL'</xsl:message></xsl:otherwise></xsl:choose></xsl:template>
Template for element MCCI_IN200101 which is the batch response wrapper. Copies from
MCCI_IN200101 to MCCI_IN200101.
Operation: copies all elements specific to the batch response wrapper as-is, except
the root element, versionCode, and interactionId. The latter are fixed to avoid version
conflicts. After copying the wrapper elements, the interaction QUPC_IN990002NL (if
available) is handed to the applicable template.
Namespace
No namespace
Match
hl7:MCCI_IN200101
Mode
#default
Import precedence
0
Source
<xsl:template match="hl7:MCCI_IN200101" name="BatchResponseWrapper"><!-- NOTE: do not leave active Schematron/XML Schema references in production --><!--xsl:processing-instruction name="nictiz">status="test"</xsl:processing-instruction--><!--xsl:processing-instruction name="oxygen">SCHSchema="../schematron/haz-pqr-mk-r.sch"</xsl:processing-instruction--><!--xsl:processing-instruction name="oxygen">SCHSchema="../schematron/MCCI_IN200101.sch"</xsl:processing-instruction--><!--xsl:element name="MCCI_IN200101" namespace="urn:hl7-org:v3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:hl7-org:v3 ../schemas/MCCI_IN200101.xsd"--><xsl:element name="MCCI_IN200101" namespace="urn:hl7-org:v3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><xsl:copy-of select="hl7:id" copy-namespaces="no"/><xsl:copy-of select="hl7:creationTime" copy-namespaces="no"/><versionCode code="NICTIZEd2005-Okt"/><interactionId extension="MCCI_IN200101" root="2.16.840.1.113883.1.6"/><xsl:copy-of select="hl7:profileId" copy-namespaces="no"/><xsl:copy-of select="hl7:transmissionQuantity" copy-namespaces="no"/><xsl:copy-of select="hl7:acknowledgement" copy-namespaces="no"/><xsl:copy-of select="hl7:receiver" copy-namespaces="no"/><xsl:copy-of select="hl7:sender" copy-namespaces="no"/><xsl:apply-templates select="hl7:QUPC_IN990002NL"/></xsl:element></xsl:template>
Template for element 'QUPC_IN443130NL', 'QUPC_IN443131NL', 'QUPC_IN443132NL' which
is the professional summary query interaction. Copies to QUPC_IN990001NL, ignoring
the interaction specified in the parameter g_outputInteractionId This template always called directly.
Operation: copies all wrapper elements specific to the interaction as-is, except the
root element, versionCode, interactionId, profileId, processingCode, processingModeCode,
and acceptAckCode. The latter are fixed to avoid version conflicts.
Template for element QUPC_IN990002NL which is the professional summary response interaction.
Copies QUPC_IN990002NL to the interaction specified in the parameter g_outputInteractionId This template called either directly, or via the MCCI_IN200101 batch response template.
Operation: copies all wrapper elements specific to the interaction as-is, except the
root element, versionCode, interactionId, profileId, processingCode, processingModeCode,
and acceptAckCode. The latter are fixed to avoid version conflicts.
Template for element PrimaryCareProvision which is the professional summary payload.
Copies PrimaryCareProvision element to CareProvisionEvent element, based on output
template g_outputTemplateId
Operation:
First builds an index of ids for encounters with their activities and separate activities.
This index is used to filter on
PrimaryCareProvision/author - copy any as author via R_AssignedEntity Universal. Add time, modeCode, signatureCode with @nullFlavor="NI" to satisfy output requirements
<xsl:template match="hl7:PrimaryCareProvision" name="PrimaryCareProvision"><!-- Holds an index of identifiers for specific elements that should be copied --><xsl:variable name="copyIndex"><x><!-- First get activities under encounters --><xsl:choose><!-- handle supported interactions in a special way. Currently all interactions get the same encounters from no longer than 10 days ago.
If this is to be different in the future, then the xs:when needs to be split up per interaction. --><xsl:when test="$g_outputInteractionId='QUPC_IN443230NL' or $g_outputInteractionId='QUPC_IN443231NL' or $g_outputInteractionId='QUPC_IN443232NL'"><xsl:for-each select=".//hl7:component1/hl7:encounter"><xsl:variable name="effVal" select="if (hl7:effectiveTime/@value) then (number(substring(concat(hl7:effectiveTime/@value,'00000000000000'),1,14))) else (0)"/><xsl:variable name="effValLow" select="if (hl7:effectiveTime/hl7:low/@value) then (number(substring(concat(hl7:effectiveTime/hl7:low/@value,'00000000000000'),1,14))) else (0)"/><xsl:variable name="effValHigh" select="if (hl7:effectiveTime/hl7:high/@value) then (number(substring(concat(hl7:effectiveTime/hl7:high/@value,'00000000000000'),1,14))) else (0)"/><xsl:if test="number($tsToday)-$effVal <= $tenDaysAgo or number($tsToday)-$effValLow <= $tenDaysAgo or number($tsToday)-$effValHigh <= $tenDaysAgo"><xsl:copy-of select="hl7:id" copy-namespaces="no"/><xsub type="encounter"><xsl:copy-of select="hl7:component/hl7:*[hl7:JournalEntry or hl7:observation or hl7:ObservationDx]/hl7:id" copy-namespaces="no"/></xsub></xsl:if></xsl:for-each></xsl:when><!-- otherwise copy all encounters...may need to reverse this by not copying any encounter...
note that if a new interactions needs to be supported, you probably need an extra xsl:when --><xsl:otherwise><xsl:copy-of select=".//hl7:component1/hl7:encounter/hl7:id" copy-namespaces="no"/><xsub type="encounter-activity"><xsl:copy-of select="hl7:component/hl7:*/hl7:id" copy-namespaces="no"/></xsub></xsl:otherwise></xsl:choose><!-- Next get activities not under encounters --><xsub type="activity"><xsl:choose><!-- handle supported interactions in a special way. Currently all interactions get the same acts/observations from no longer than 10 days ago.
If this is to be different in the future, then the xs:when needs to be split up per interaction.
NOTE: Act is not currently in the PS specification. It is planned to be supported with two different types and two different periods
1. Correspondance up to 10 days ago
2. Also known at up to 2 years ago
--><xsl:when test="$g_outputInteractionId='QUPC_IN443230NL' or $g_outputInteractionId='QUPC_IN443231NL' or $g_outputInteractionId='QUPC_IN443232NL'"><xsl:for-each select=".//hl7:component2/hl7:JournalEntry | .//hl7:component2/hl7:ObservationDx | .//hl7:component2/hl7:observation"><xsl:variable name="effVal" select="if (hl7:effectiveTime/@value) then (number(substring(concat(hl7:effectiveTime/@value,'00000000000000'),1,14))) else (0)"/><xsl:variable name="effValLow" select="if (hl7:effectiveTime/hl7:low/@value) then (number(substring(concat(hl7:effectiveTime/hl7:low/@value,'00000000000000'),1,14))) else (0)"/><xsl:variable name="effValHigh" select="if (hl7:effectiveTime/hl7:high/@value) then (number(substring(concat(hl7:effectiveTime/hl7:high/@value,'00000000000000'),1,14))) else (0)"/><xsl:if test="number($tsToday)-$effVal <= $tenDaysAgo or number($tsToday)-$effValLow <= $tenDaysAgo or number($tsToday)-$effValHigh <= $tenDaysAgo"><xsl:copy-of select="hl7:id" copy-namespaces="no"/></xsl:if></xsl:for-each></xsl:when><!-- otherwise copy all observations...may need to reverse this by not copying any observation...
note that if a new interactions needs to be supported, you probably need an extra xsl:when --><xsl:otherwise><xsl:copy-of select=".//hl7:component2/hl7:observation/hl7:id" copy-namespaces="no"/></xsl:otherwise></xsl:choose></xsub></x></xsl:variable><CareProvisionEvent classCode="PCPR" moodCode="EVN"><templateId root="{$g_outputTemplateId}"/><xsl:copy-of select="hl7:id" copy-namespaces="no"/><xsl:copy-of select="hl7:statusCode" copy-namespaces="no"/><xsl:apply-templates select="hl7:effectiveTime"/><!-- participations --><xsl:for-each select="hl7:subject"><recordTarget typeCode="RCT" contextControlCode="OP"><xsl:apply-templates select="hl7:Patient"/></recordTarget></xsl:for-each><xsl:for-each select="hl7:performer"><performer typeCode="PRF" contextControlCode="OP"><assignedParty classCode="ASSIGNED"><xsl:apply-templates select="hl7:AssignedEntity" mode="R_AssignedEntity"/></assignedParty></performer></xsl:for-each><xsl:for-each select="hl7:author"><author typeCode="AUT" contextControlCode="OP"><time nullFlavor="NI"/><modeCode nullFlavor="NI"/><signatureCode nullFlavor="NI"/><assignedParty classCode="ASSIGNED"><xsl:apply-templates select="hl7:AssignedEntity" mode="R_AssignedEntity"/></assignedParty></author></xsl:for-each><!-- NOT mapping PrimaryCareProvision/custodian --><!-- NOT mapping PrimaryCareProvision/dataEnterer --><!-- actrelationships --><!-- EpisodeOfConditions must have at least description in hl7:text or a diagnosis with and code and effectiveTime, otherwise get XML Schema invalid output, and a problem without some form of diagnosis does not make sense --><xsl:for-each select="hl7:component7[hl7:episodeOfCondition/hl7:text | hl7:episodeOfCondition/hl7:reason/hl7:ObservationDx[hl7:code/@code and hl7:effectiveTime//@value]]"><xsl:comment> source: component7/edisodeOfCondition </xsl:comment><reason typeCode="RSON" contextConductionInd="true"><!--sequenceNumber value="1"/--><xsl:apply-templates select="hl7:episodeOfCondition"><xsl:with-param name="copyIndex" select="$copyIndex"/></xsl:apply-templates></reason></xsl:for-each><!-- Encounters --><xsl:for-each select="hl7:component1"><xsl:variable name="encIdRoot" select="(hl7:encounter/hl7:id)[1]/@root"/><xsl:variable name="encIdExt" select="(hl7:encounter/hl7:id)[1]/@extension"/><xsl:if test="$copyIndex//hl7:id[@root=$encIdRoot and (not(@extension) or @extension=$encIdExt)]"><xsl:comment> source: component1/encounter </xsl:comment><pertinentInformation3 typeCode="PERT" contextConductionInd="true"><xsl:apply-templates select="hl7:encounter"/></pertinentInformation3></xsl:if></xsl:for-each><!-- Activities --><!-- NOT mapping act --><!-- NOT mapping Prescription --><!-- NOT mapping MedicationDispenseEvent --><!-- NOT mapping ProcedureEvent --><xsl:for-each select="hl7:component2"><xsl:choose><xsl:when test="hl7:JournalEntry or hl7:ObservationDx or hl7:observation"><xsl:variable name="effVal" select="if (hl7:*/hl7:effectiveTime/@value) then (number(substring(concat(hl7:*/hl7:effectiveTime/@value,'00000000000000'),1,14))) else (0)"/><xsl:variable name="effValLow" select="if (hl7:*/hl7:effectiveTime/hl7:low/@value) then (number(substring(concat(hl7:*/hl7:effectiveTime/hl7:low/@value,'00000000000000'),1,14))) else (0)"/><xsl:variable name="effValHigh" select="if (hl7:*/hl7:effectiveTime/hl7:high/@value) then (number(substring(concat(hl7:*/hl7:effectiveTime/hl7:high/@value,'00000000000000'),1,14))) else (0)"/><xsl:choose><xsl:when test="number($tsToday)-$effVal <= $tenDaysAgo or number($tsToday)-$effValLow <= $tenDaysAgo or number($tsToday)-$effValHigh <= $tenDaysAgo"><xsl:comment> source: component2/Activities choicebox </xsl:comment><pertinentInformation3 typeCode="PERT" contextConductionInd="true"><xsl:apply-templates select="hl7:observation" mode="Activity"/><xsl:apply-templates select="hl7:JournalEntry"/><xsl:apply-templates select="hl7:ObservationDx"/></pertinentInformation3></xsl:when><xsl:otherwise><!-- TODO: debug only: remove this, because it may give the recipient too much info --><xsl:comment> source: skipped component2/<xsl:value-of select="local-name(hl7:*[1])"/> because it was older than agreed upon </xsl:comment></xsl:otherwise></xsl:choose></xsl:when><xsl:otherwise><!-- TODO: debug only: remove this, because it may give the recipient too much info --><xsl:comment> source: skipped component2/<xsl:value-of select="local-name(hl7:*[1])"/> because it was not a supported output activity </xsl:comment></xsl:otherwise></xsl:choose></xsl:for-each><!-- ContraIndications --><xsl:for-each select="hl7:component3"><pertinentInformation3 typeCode="PERT" contextConductionInd="true"><xsl:apply-templates select="hl7:ContraIndication"/></pertinentInformation3></xsl:for-each><!-- ObservationIntolerances --><xsl:for-each select="hl7:component4"><pertinentInformation3 typeCode="PERT" contextConductionInd="true"><xsl:apply-templates select="hl7:ObservationIntolerance"/></pertinentInformation3></xsl:for-each><!-- Annotations --><xsl:for-each select="hl7:pertinentInformation"><xsl:comment> source: pertinentInformation (Annotation) </xsl:comment><pertinentInformation3 typeCode="PERT" contextConductionInd="true"><xsl:apply-templates select="hl7:pertinentAnnotationObsEvent"/></pertinentInformation3></xsl:for-each></CareProvisionEvent></xsl:template>
Template for element subject/Patient containing R_PatientNL Universal (COCT_MT050000NL).
Copies Patient element to patient element based on output template 2.16.840.1.113883.2.4.6.10.70.18.
Template for element subject/Patient containing R_PatientNL Identified (COCT_MT050001NL).
Copies Patient element to patient element based on output template 2.16.840.1.113883.2.4.6.10.70.23.
Template for elements AssignedEntity (R_AssignedEntityNL_PO Universal (COCT_MT090000NL2)),
assignedEntity1 (R_AssignedEntity Universal (COCT_MT090000)), and AssignedPerson (R_AssignedPerson
Universal (COCT_MT090100)). Copies sub elements to elements based on output template
2.16.840.1.113883.2.4.6.10.70.20.
Background: in the XML Schemas COCT_MT090000.xsd and COCT_MT090000NL2.xsd there is
an error which is true for many of the schemas generated around that same time.
It has a mandatory element Organization, which should have been an optional element
representedOrganization. This element is supposed to hold
the -Scoping Organization- for the main AssignedEntity. The AssignedEntity itself
might be a person or an organization, and the name should
go into respectively into the -Playing Entity- assignedPerson or assignedOrganization.
However: since Organization is a mandatory element in the Schema, if an implementer
needed to implement an organization as AssignedEntity he did
not have a scoping Organization for it, and would put the name for the -playing- entity
behind AssignedEntity in the Organization element to satisfy
the XML Schema. It would even occur that AssignedEntity/code, addr, telecom, statusCode
where placed in Organization. We would loose that information in that case.
To fix this error in this mapping so we don't impose the same problem onto the result
document, but taking into account that some
implementers might implemented both assignedPerson/assignedOrganization AND Organization
(which is the right way to implement legal by the way) we
will handle as follows:
if AssignedEntity/code, addr, telecom, or statusCode is missing, but Organization/id
matches AssignedEntity/id, then map Organization/code, addr, telecom, statusCode to
AssignedEntity
if both assignedPerson/assignedOrganization and Organization are present: map both.
if assignedPerson/assignedOrganization are not present and just Organization is present:
map Organization into assignedOrganization
AssignedEntity/code - any as-is, if missing and AssignedEntity/id=AssignedEntity/Organization/id,
then copy AssignedEntity/Organization/code
AssignedEntity/addr - any as-is, if missing and AssignedEntity/id=AssignedEntity/Organization/id,
then copy AssignedEntity/Organization/addr
AssignedEntity/telecom - any as-is, if missing and AssignedEntity/id=AssignedEntity/Organization/id,
then copy AssignedEntity/Organization/telecom
AssignedEntity/statusCode - any as-is, if missing and AssignedEntity/id=AssignedEntity/Organization/id,
then copy AssignedEntity/Organization/statusCode
AssignedEntity/effectiveTime - no mapping
AssignedEntity/certificateText - no mapping
AssignedEntity/assignedPerson / AssignedEntity/assignedOrganization - one of:
assignedPerson/name - if present any as-is
assignedOrganization/name - if present any as-is
AssignedEntity/Organization/name - if both assignedPerson and assignedOrganization
are missing and if present any as-is
AssignedEntity/Organization - if present and not already copied before, and if not
just contains id/@nullFlavor, as-is to representedOrganization
Organization/id - any as-is or with nullFlavor="NI" or none are present
<xsl:template match="hl7:AssignedEntity | hl7:assignedEntity1 | hl7:AssignedPerson" mode="R_AssignedEntity" name="R_AssignedEntityUniversal"><xsl:variable name="aeIdRoot" select="hl7:id[1]/@root"/><xsl:variable name="aeIdExt" select="hl7:id[1]/@extension"/><xsl:choose><xsl:when test="hl7:assignedPerson or hl7:assignedOrganization or hl7:Organization/hl7:id[@root=$aeIdRoot and @extension=$aeIdExt]"><!-- if there is a name use Universal template --><templateId root="2.16.840.1.113883.2.4.6.10.70.20"/></xsl:when><xsl:otherwise><!-- otherwise use Identified template --><templateId root="2.16.840.1.113883.2.4.6.10.70.21"/></xsl:otherwise></xsl:choose><xsl:copy-of select="hl7:id" copy-namespaces="no"/><!-- copy local element before checking Organization --><xsl:choose><xsl:when test="hl7:code"><xsl:copy-of select="hl7:code" copy-namespaces="no"/></xsl:when><xsl:when test="hl7:Organization/hl7:id[@root=$aeIdRoot and @extension=$aeIdExt]"><xsl:copy-of select="hl7:Organization/hl7:code" copy-namespaces="no"/></xsl:when></xsl:choose><!-- copy local element before checking Organization --><xsl:choose><xsl:when test="hl7:addr"><xsl:copy-of select="hl7:addr" copy-namespaces="no"/></xsl:when><xsl:when test="hl7:Organization/hl7:id[@root=$aeIdRoot and @extension=$aeIdExt]"><xsl:copy-of select="hl7:Organization/hl7:addr" copy-namespaces="no"/></xsl:when></xsl:choose><!-- copy local element before checking Organization --><xsl:choose><xsl:when test="hl7:telecom"><xsl:copy-of select="hl7:telecom" copy-namespaces="no"/></xsl:when><xsl:when test="hl7:Organization/hl7:id[@root=$aeIdRoot and @extension=$aeIdExt]"><xsl:copy-of select="hl7:Organization/hl7:telecom" copy-namespaces="no"/></xsl:when></xsl:choose><!-- copy local element before checking Organization --><xsl:choose><xsl:when test="hl7:statusCode"><xsl:copy-of select="hl7:statusCode" copy-namespaces="no"/></xsl:when><xsl:when test="hl7:Organization/hl7:id[@root=$aeIdRoot and @extension=$aeIdExt]"><xsl:copy-of select="hl7:Organization/hl7:statusCode" copy-namespaces="no"/></xsl:when></xsl:choose><!-- copy local element before checking Organization --><xsl:choose><xsl:when test="hl7:assignedPerson"><assignedPerson classCode="PSN" determinerCode="INSTANCE"><xsl:copy-of select="hl7:assignedPerson/hl7:name" copy-namespaces="no"/></assignedPerson></xsl:when><xsl:when test="hl7:assignedOrganization"><assignedOrganization classCode="ORG" determinerCode="INSTANCE"><xsl:copy-of select="hl7:assignedOrganization/hl7:name" copy-namespaces="no"/></assignedOrganization></xsl:when><xsl:when test="hl7:Organization/hl7:id[@root=$aeIdRoot and @extension=$aeIdExt]"><assignedOrganization classCode="ORG" determinerCode="INSTANCE"><xsl:copy-of select="hl7:Organization/hl7:name" copy-namespaces="no"/></assignedOrganization></xsl:when></xsl:choose><!-- copy Organization only if not already copied into assignedParty and/or assignedOrganization (representedOrganization is optional in output) --><xsl:if test="hl7:assignedPerson or hl7:assignedOrganization or not(hl7:Organization/hl7:id[@root=$aeIdRoot and @extension=$aeIdExt])"><!-- copy Organization if not just id/@nullFlavor. --><xsl:if test="not(hl7:Organization/hl7:id/@nullFlavor) and count(hl7:Organization/hl7:*) >1"><representedOrganization classCode="ORG" determinerCode="INSTANCE"><xsl:copy-of select="hl7:Organization/hl7:id" copy-namespaces="no"/><xsl:copy-of select="hl7:Organization/hl7:code" copy-namespaces="no"/><xsl:copy-of select="hl7:Organization/hl7:name" copy-namespaces="no"/><xsl:copy-of select="hl7:Organization/hl7:desc" copy-namespaces="no"/><xsl:copy-of select="hl7:Organization/hl7:statusCode" copy-namespaces="no"/><xsl:copy-of select="hl7:Organization/hl7:telecom" copy-namespaces="no"/><xsl:copy-of select="hl7:Organization/hl7:addr" copy-namespaces="no"/><xsl:apply-templates select="hl7:Organization/hl7:part" mode="OrganizationPart"/><xsl:apply-templates select="hl7:Organization/hl7:part-of" mode="OrganizationPart"/></representedOrganization></xsl:if></xsl:if></xsl:template>
Template for element Organization/part from E_Organization Universal. Copies part
element to part, needs to convert two child element names, recurses into itself if
needed, and binds with OrganizationPartOf
Template for element Organization/part-of from E_Organization Universal. Copies part-of
element to part-of, needs to convert two child element names, recurses into itself
if needed, and binds with OrganizationPart
Copies actReference, if target is in output. Target is in output if target existed
in the first place and
is part of an encounter activity that gets copied, or is part of a non-encounter bound
activity. The answer
to these conditions means that the id must be in the parameter copyIndex.
We're determining/patching the correct @classCode and @moodCode on actReference ourselves
because qualification testing
in the past has been to loose to rely on.
Namespace
No namespace
Match
hl7:episodOfCare/hl7:component/hl7:actReference
Mode
#default
Parameters
QName
Namespace
Required
copyIndex
No namespace
yes
Import precedence
0
Source
<xsl:template match="hl7:episodOfCare/hl7:component/hl7:actReference" name="ActReference"><xsl:param name="copyIndex" required="yes"/><xsl:variable name="arIdRoot" select="hl7:id[1]/@root"/><xsl:variable name="arIdExt" select="hl7:id[1]/@extension"/><xsl:variable name="elTargetName" select="(ancestor::hl7:PrimaryCareProvision//hl7:*[not(local-name()='actReference')][hl7:id[@root=$arIdRoot and @extension=$arIdExt]])[1]/local-name()"/><!-- refClass checks for names regardless of whether they are copied in the whole. That doesn't do any harm and saves maintenance --><xsl:variable name="refClass"><xsl:choose><xsl:when test="$elTargetName='JournalEntry' or $elTargetName='ObservationDx' or $elTargetName='observation' or $elTargetName='Observation'"><xsl:value-of select="'OBS'"/></xsl:when><xsl:when test="$elTargetName='ProcedureEvent'"><xsl:value-of select="'PROC'"/></xsl:when><xsl:when test="$elTargetName='Referral'"><xsl:value-of select="'PCPR'"/></xsl:when><xsl:when test="$elTargetName='MedicationDispenseEvent'"><xsl:value-of select="'SPLY'"/></xsl:when><xsl:when test="$elTargetName='Prescription'"><xsl:value-of select="'SBADM'"/></xsl:when><xsl:otherwise><xsl:value-of select="''"/></xsl:otherwise></xsl:choose></xsl:variable><xsl:variable name="refMood"><xsl:choose><xsl:when test="$elTargetName='Prescription'"><xsl:value-of select="'RQO'"/></xsl:when><xsl:otherwise><xsl:value-of select="'EVN'"/></xsl:otherwise></xsl:choose></xsl:variable><xsl:choose><xsl:when test="$copyIndex//hl7:id[@root=$arIdRoot and (not(@extension) or @extension=$arIdExt)]"><reference typeCode="REFR" contextConductionInd="false"><actReference><xsl:attribute name="classCode"><xsl:value-of select="$refClass"/></xsl:attribute><xsl:attribute name="moodCode"><xsl:value-of select="$refMood"/></xsl:attribute><templateId root="2.16.840.1.113883.2.4.6.10.70.16"/><xsl:copy-of select="hl7:id" copy-namespaces="no"/></actReference></reference></xsl:when><xsl:otherwise><xsl:comment>source: skipped ActReference (target:<xsl:value-of select="$elTargetName"/>) <id root="<xsl:value-of select="$arIdRoot"/>" extension="<xsl:value-of select="$arIdExt"/>"/></xsl:comment></xsl:otherwise></xsl:choose></xsl:template>
Copies ContraIndication containing a contra indication
Namespace
No namespace
Match
hl7:ContraIndication
Mode
#default
Import precedence
0
Source
<xsl:template match="hl7:ContraIndication" name="ContraIndication"><xsl:comment>source:<xsl:value-of select="concat(local-name(../..),'/',local-name(..),'/',local-name(.))"/></xsl:comment><observation classCode="OBS" moodCode="EVN"><xsl:copy-of select="@negationInd" copy-namespaces="no"/><templateId root="2.16.840.1.113883.2.4.6.10.70.27"/><xsl:copy-of select="hl7:id" copy-namespaces="no"/><xsl:choose><!-- There have examples without @codeSystem. This should never occur in production, but patching anyway just in case --><xsl:when test="hl7:code[not(@codeSystem) and (@code='CI' or @code='DERCI')]"><code><xsl:attribute name="codeSystem"><xsl:value-of select="'2.16.840.1.113883.5.4'"/></xsl:attribute><xsl:copy-of select="hl7:code/@*" copy-namespaces="no"/></code></xsl:when><xsl:otherwise><xsl:copy-of select="hl7:code" copy-namespaces="no"/></xsl:otherwise></xsl:choose><xsl:copy-of select="hl7:text[string-length(normalize-space(text()))>0]" copy-namespaces="no"/><xsl:if test="hl7:effectiveTime[.//@value or .//@nullFlavor]"><effectiveTime><xsl:copy-of select="hl7:effectiveTime/@*" copy-namespaces="no"/><xsl:attribute name="xsi:type"><xsl:value-of select="'IVL_TS'"/></xsl:attribute><xsl:copy-of select="hl7:effectiveTime/node()" copy-namespaces="no"/></effectiveTime></xsl:if><xsl:choose><xsl:when test="hl7:value"><value><xsl:copy-of select="hl7:value/@*" copy-namespaces="no"/><xsl:attribute name="xsi:type"><xsl:value-of select="'CE'"/></xsl:attribute><xsl:copy-of select="hl7:value/node()" copy-namespaces="no"/></value></xsl:when><xsl:otherwise><value xsi:type="CE" nullFlavor="UNK"/></xsl:otherwise></xsl:choose><xsl:for-each select="hl7:author"><author typeCode="AUT" contextControlCode="ON"><!-- NOTE: time is mandatory in output, but optional in input, Now getting the century part of diagnosis itself, which is pretty meaningless, but validates --><xsl:choose><xsl:when test="hl7:time/@value"><xsl:copy-of select="hl7:time" copy-namespaces="no"/></xsl:when><xsl:otherwise><time value="{substring((parent::hl7:ObservationDx/hl7:effectiveTime//@value)[1],1,2)}"/></xsl:otherwise></xsl:choose><xsl:apply-templates select="hl7:AssignedPerson" mode="R_AssignedPersonIdentified2AssignedEntity"/></author></xsl:for-each></observation></xsl:template>
Copies ObservationIntolerance containing an Observation Intolerance
Namespace
No namespace
Match
hl7:ObservationIntolerance
Mode
#default
Import precedence
0
Source
<xsl:template match="hl7:ObservationIntolerance" name="ObservationIntolerance"><xsl:comment>source:<xsl:value-of select="concat(local-name(../..),'/',local-name(..),'/',local-name(.))"/></xsl:comment><observation classCode="OBS" moodCode="EVN"><xsl:copy-of select="@negationInd" copy-namespaces="no"/><templateId root="2.16.840.1.113883.2.4.6.10.70.26"/><xsl:copy-of select="hl7:id" copy-namespaces="no"/><xsl:choose><!-- There have examples without @codeSystem. This should never occur in production, but patching anyway just in case --><xsl:when test="hl7:code[not(@codeSystem) and (@code='DINT' or @code='INTLRNC')]"><code><xsl:attribute name="codeSystem"><xsl:value-of select="'2.16.840.1.113883.5.4'"/></xsl:attribute><xsl:copy-of select="hl7:code/@*" copy-namespaces="no"/></code></xsl:when><xsl:otherwise><xsl:copy-of select="hl7:code" copy-namespaces="no"/></xsl:otherwise></xsl:choose><xsl:copy-of select="hl7:text[string-length(normalize-space(text()))>0]" copy-namespaces="no"/><xsl:copy-of select="hl7:statusCode[@code]" copy-namespaces="no"/><xsl:if test="hl7:effectiveTime[.//@value or .//@nullFlavor]"><effectiveTime><xsl:copy-of select="hl7:effectiveTime/@*" copy-namespaces="no"/><xsl:attribute name="xsi:type"><xsl:value-of select="'IVL_TS'"/></xsl:attribute><xsl:copy-of select="hl7:effectiveTime/node()" copy-namespaces="no"/></effectiveTime></xsl:if><xsl:choose><xsl:when test="hl7:value"><value><xsl:copy-of select="hl7:value/@*" copy-namespaces="no"/><xsl:attribute name="xsi:type"><xsl:value-of select="'CE'"/></xsl:attribute><xsl:copy-of select="hl7:value/node()" copy-namespaces="no"/></value></xsl:when><xsl:otherwise><value xsi:type="CE" nullFlavor="UNK"/></xsl:otherwise></xsl:choose><xsl:for-each select="hl7:author"><author typeCode="AUT" contextControlCode="ON"><!-- NOTE: time is mandatory in output, but optional in input, Now getting the century part of diagnosis itself, which is pretty meaningless, but validates --><xsl:choose><xsl:when test="hl7:time/@value"><xsl:copy-of select="hl7:time" copy-namespaces="no"/></xsl:when><xsl:otherwise><time value="{substring((parent::hl7:ObservationDx/hl7:effectiveTime//@value)[1],1,2)}"/></xsl:otherwise></xsl:choose><xsl:apply-templates select="hl7:AssignedPerson" mode="R_AssignedPersonIdentified2AssignedEntity"/></author></xsl:for-each></observation></xsl:template>
<xsl:template match="hl7:ObservationDx" name="ActivityObservationDx"><xsl:comment>source:<xsl:value-of select="concat(local-name(../..),'/',local-name(..),'/',local-name(.))"/></xsl:comment><observation classCode="OBS" moodCode="EVN"><templateId root="2.16.840.1.113883.2.4.6.10.70.5"/><xsl:copy-of select="hl7:id" copy-namespaces="no"/><xsl:choose><!-- There have examples without @codeSystem. This should never occur in production, but patching anyway just in case --><xsl:when test="hl7:code[not(@codeSystem) and (@code='ADMDX' or @code='DISDX')]"><code><xsl:attribute name="codeSystem"><xsl:value-of select="'2.16.840.1.113883.5.4'"/></xsl:attribute><xsl:copy-of select="hl7:code/@*" copy-namespaces="no"/></code></xsl:when><xsl:otherwise><xsl:copy-of select="hl7:code" copy-namespaces="no"/></xsl:otherwise></xsl:choose><xsl:if test="hl7:value/@displayName"><text><xsl:value-of select="hl7:value/@displayName"/></text></xsl:if><xsl:if test="hl7:effectiveTime[.//@value or .//@nullFlavor]"><effectiveTime><xsl:copy-of select="hl7:effectiveTime/@*" copy-namespaces="no"/><xsl:attribute name="xsi:type"><xsl:value-of select="'IVL_TS'"/></xsl:attribute><xsl:copy-of select="hl7:effectiveTime/node()" copy-namespaces="no"/></effectiveTime></xsl:if><xsl:choose><xsl:when test="hl7:value"><value><xsl:copy-of select="hl7:value/@*" copy-namespaces="no"/><xsl:attribute name="xsi:type"><xsl:value-of select="'CE'"/></xsl:attribute><xsl:copy-of select="hl7:value/node()" copy-namespaces="no"/></value></xsl:when><xsl:otherwise><value xsi:type="CE" nullFlavor="UNK"/></xsl:otherwise></xsl:choose><xsl:for-each select="hl7:performer"><performer typeCode="PRF" contextControlCode="ON"><xsl:apply-templates select="hl7:AssignedPerson" mode="R_AssignedPersonIdentified"/></performer></xsl:for-each><xsl:for-each select="hl7:author"><author typeCode="AUT" contextControlCode="ON"><!-- NOTE: time is mandatory in output, but optional in input, Now getting the century part of diagnosis itself, which is pretty meaningless, but validates --><xsl:choose><xsl:when test="hl7:time/@value"><xsl:copy-of select="hl7:time" copy-namespaces="no"/></xsl:when><xsl:otherwise><time value="{substring((parent::hl7:ObservationDx/hl7:effectiveTime//@value)[1],1,2)}"/></xsl:otherwise></xsl:choose><xsl:apply-templates select="hl7:AssignedPerson" mode="R_AssignedPersonIdentified2AssignedEntity"/><xsl:apply-templates select="hl7:Patient" mode="R_PatientNLIdentified"/></author></xsl:for-each></observation></xsl:template>
Patch effectiveTime for common mistakes: have low and high with just a date+hour,
date+hour+minute, or just a date. Fix by making low start of the day and high end
of the day because that's what it semantically is anyway
Namespace
No namespace
Match
hl7:effectiveTime
Mode
#default
Parameters
QName
Namespace
Select
xsiType
No namespace
''
Import precedence
0
Source
<xsl:template match="hl7:effectiveTime" name="effectiveTime"><xsl:param name="xsiType" select="''"/><xsl:choose><xsl:when test="hl7:low/@value=hl7:high/@value and matches(hl7:low/@value,'^\d{12}$')"><!-- patch date+hour+minute and overwrite xsi:type if not '' --><effectiveTime><xsl:copy-of select="@*" copy-namespaces="no"/><xsl:if test="not($xsiType='')"><xsl:attribute name="xsi:type"><xsl:value-of select="$xsiType"/></xsl:attribute></xsl:if><low><xsl:copy-of select="hl7:low/@*" copy-namespaces="no"/><xsl:attribute name="value"><xsl:value-of select="concat(hl7:low/@value,'00')"/></xsl:attribute></low><high><xsl:copy-of select="hl7:high/@*" copy-namespaces="no"/><xsl:attribute name="value"><xsl:value-of select="concat(hl7:high/@value,'59')"/></xsl:attribute></high></effectiveTime></xsl:when><xsl:when test="hl7:low/@value=hl7:high/@value and matches(hl7:low/@value,'^\d{10}$')"><!-- patch date+hour and overwrite xsi:type if not '' --><effectiveTime><xsl:copy-of select="@*" copy-namespaces="no"/><xsl:if test="not($xsiType='')"><xsl:attribute name="xsi:type"><xsl:value-of select="$xsiType"/></xsl:attribute></xsl:if><low><xsl:copy-of select="hl7:low/@*" copy-namespaces="no"/><xsl:attribute name="value"><xsl:value-of select="concat(hl7:low/@value,'0000')"/></xsl:attribute></low><high><xsl:copy-of select="hl7:high/@*" copy-namespaces="no"/><xsl:attribute name="value"><xsl:value-of select="concat(hl7:high/@value,'5959')"/></xsl:attribute></high></effectiveTime></xsl:when><xsl:when test="hl7:low/@value=hl7:high/@value and matches(hl7:low/@value,'^\d{8}$')"><!-- patch date and overwrite xsi:type if not '' --><effectiveTime><xsl:copy-of select="@*" copy-namespaces="no"/><xsl:if test="not($xsiType='')"><xsl:attribute name="xsi:type"><xsl:value-of select="$xsiType"/></xsl:attribute></xsl:if><low><xsl:copy-of select="hl7:low/@*" copy-namespaces="no"/><xsl:attribute name="value"><xsl:value-of select="concat(hl7:low/@value,'000000')"/></xsl:attribute></low><high><xsl:copy-of select="hl7:high/@*" copy-namespaces="no"/><xsl:attribute name="value"><xsl:value-of select="concat(hl7:high/@value,'235959')"/></xsl:attribute></high></effectiveTime></xsl:when><xsl:when test="not($xsiType='')"><!-- just overwrite xsi:type --><effectiveTime><xsl:copy-of select="@*" copy-namespaces="no"/><xsl:if test="not($xsiType='')"><xsl:attribute name="xsi:type"><xsl:value-of select="$xsiType"/></xsl:attribute></xsl:if><xsl:copy-of select="hl7:*" copy-namespaces="no"/></effectiveTime></xsl:when><xsl:otherwise><xsl:copy-of select="self::hl7:effectiveTime" copy-namespaces="no"/></xsl:otherwise></xsl:choose></xsl:template>
<xsl:template match="hl7:code" mode="EncounterCode" name="EncounterCode"><xsl:choose><xsl:when test="@code='99' and @codeSystem='2.16.840.1.113883.2.4.4.30.14'"><!-- Patch for EncounterCode. code="99" displayName="overig" was legal in v3, but not in the target v7. In v7 this should copy into nullFlavor="OTH" --><code nullFlavor="OTH" codeSystem="2.16.840.1.113883.2.4.4.30.14"><xsl:if test="@displayName"><originalText><xsl:value-of select="@displayName"/></originalText></xsl:if><xsl:copy-of select="hl7:translation" copy-namespaces="no"/></code></xsl:when><xsl:when test="matches(@code,'^[1-9]$') and @codeSystem='2.16.840.1.113883.2.4.4.30.14'"><!-- Patch for EncounterCode. code="1-9" codeSystem="2.16.840.1.113883.2.4.4.30.14" was never legal, but some systems apparently had a numeric code thus omitting the leading zero in the zero --><code><xsl:copy-of select="@*" copy-namespaces="no"/><xsl:attribute name="code"><xsl:value-of select="concat('0',@code)"/></xsl:attribute><xsl:copy-of select="hl7:*" copy-namespaces="no"/></code></xsl:when><xsl:when test="matches(@code,'^[0-9]{3}$') and @codeSystem='2.16.840.1.113883.2.4.4.30.14'"><!-- Patch for EncounterCode. code="nnn" codeSystem="2.16.840.1.113883.2.4.4.30.14" was never legal, but some systems apparently implemented Codesystem Tabel 15 as-if it were CodeSystem Tabel 14 --><code nullFlavor="OTH" codeSystem="2.16.840.1.113883.2.4.4.30.14"><translation code="{@code}" codeSystem="2.16.840.1.113883.2.4.4.30.15" displayName="{@displayName}"/></code></xsl:when><xsl:otherwise><xsl:copy-of select="self::hl7:*" copy-namespaces="no"/></xsl:otherwise></xsl:choose></xsl:template>
<xsl:template name="sanityCheck"><xsl:if test="string-length($g_outputInteractionId)=0"><xsl:message terminate="yes">[error] Required parameter g_outputInteractionId MUST have a value, e.g. 'QUPC_IN443230NL'. Exiting...</xsl:message></xsl:if><xsl:if test="not(string-length($g_tsToday)=14 and translate($g_tsToday,'0123456789','')='')"><xsl:message terminate="yes">[error] Required parameter g_tsToday MUST have the format YYYYMMddhhmmss (14 long and numeric). Found '<xsl:value-of select="$g_tsToday"/>'. Exiting...</xsl:message></xsl:if></xsl:template>
g_outputInteractionId is a REQUIRED parameter. The output interaction of this XSL, the parameter g_outputTemplateId and some of the contents depend on the value of this parameter.
g_outputTemplateId is an OPTIONAL parameter. See g_outputInteractionId for supported values
TemplateId that should be generated by this transformation, defaults for known interactionIds
but may be overridden. Generally this should NOT be necessary.
g_tsToday is an OPTIONAL parameter. It will contain the current date/time as a timestamp in
the format YYYYMMddhhmmss. But for testing purposes it is possible to override this
date with something in the past or future. This date is used to do date filtering
against. Most filtering is done based on "not more than 10 days ago". See also tenDaysAgo