Adapted and maintained by: Alexander Henket, Nictiz, The Netherlands, henket(a)nictiz.nl
Purpose: Provide general purpose display of CDA release 2 (Specification: ANSI/HL7 CDAR2)
and CDA release 3 (Specification: currently in ballot) documents, and be a starting
point for people interested in extending the display. This stylesheet displays all
section content, but does not try to render each and every header attribute. For header
attributes it tries to be smart in displaying essentials, which is still a lot.
License: Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
History: This stylesheet stands on the shoulders of giants. The stylesheet is the cumulative
work of several developers; the most significant prior milestones were the foundation
work from HL7
Germany and Finland (Tyylitiedosto) and HL7 US (Calvin Beebe), and the presentation
approach from Tony Schaller, medshare GmbH provided at IHIC 2009. The starting point
for this work was/is hosted at
http://www.lantanagroup.com/resources/tools/.
TODO
Fix for Mobile Safari (iOS 6): doesn't support opening the table of contents
Added new parameters for skipping the rendering of the CDA header info at the top
of the document (dohtmlheader) and/or footer (dohtmlfooter)
Fix for visibility in the TOC of empty sections as specified by the StrucDoc WG with
section/@nullFlavor
Fix in documentationOf: don't render @classCode if ACT as that doesn't hold information,
and improved serviceEvent/performer contact detail rendering
Fix for missing space in rendering of time intervals
Update localization function for the compressed l10n structure
Update menu behavior. Now only expands sublevels (if any) when hovering the parent
04/11/2018 AH
Updated rendering of documentationOf/serviceEvent/@classCode so it does not render
if it is 'ACT'
Fixed a bug in rendering documentationOf/serviceEvent/code (it was inadvertently not
rendered)
Added rendering of documentationOf/serviceEvent/performer name in the document header
Added rendering of documentationOf/serviceEvent/performer contact details in the document
footer
Fixed l10n for keys typeCode-PRP, typeCode-PPRP and typeCode-SPRP. Each last P should
have been an F.
Little tweak to author to avoid rendering of additional commas when certain content
is missing
Skip timestamp seconds when they are 00. Skip minutes and seconds when they are 00:00.
Both for readability.
03/24/2018 AH
Added parameter menu-depth with min 1, max 3, default 1 (the way it always has been)
-- temporarily left on 3 for browser testing
02/16/2018 AH
Moved header authenticator so it is right above legalAuthenticator instead of just
under participant
Improved readability. Moved contact details for all header participants (recordTarget,
author, informant, authenticator, legalAuthenticator, ...) to the right instead of
underneath the participant name.
02/15/2018 AH
Fixed rendering of serviceEvent/code, location/healthCareFacility/id, order/code,
order/priorityCode, consent/code, consent/statusCode
Fixed casing of "inFulfillmentOf" and added call to it under documentationOf (GForge#3169)
Render recordTarget regardless of nullFlavor in id. (GForge#3590)
Added support for encompassingEncounter dischargeDispositionCode, sdtc:admissionReferralSourceCode,
encounterParticipant
Added support for ClinicalDocument/versionNumber, ClinicalDocument/setId, and relatedDocument
(it was not called)
(CDA R2.1) Added support for hl7:admissionReferralSourceCode
(CDA R2.1) Added support for Person/desc as div under name
(CDA R2.1) Added support for Person/birthTime
(CDA R2.1) Added support for relatedDocument/@inversionInd
(CDA R2.1) Added support for serviceEvent/statusCode
(CDA R2.1) Added support for section subject/relatedSubject/subject/birthTime | deceasedTime
| deceasedInd | multipleBirthInd | multipleBirthOrderNumber | raceCode | ehtnicGroupCode
12/15/2017 AH
Reimplemented security fix from Rick Geimer, Lantana, that does full checking on narrative
table components
Fixed capitals in iframe properties WIDTH and HEIGHT
Added support for looking up an author organization name based on orgsanization id
Fixed getting the relatedDocument/parentDocument/id
Enhanced rendering of date/time. Now renders with AM/PM in English and with h or u
on 24h clock otherwise if at least hours are present.
10/20/2014 AH
Fixed support for recordTarget/patient extensions deceasedInd/deceasedTime and multipleBirthInd/multipleBirthOrderNumber.
They were inadvertently called in the HL7 namespace.
10/13/2014 AH
Fixed @ID by adding it to whatever in scope element (div, sup, sub, a, etc.) as @id.
To this end the separate calls were replaced by a central call in mode 'handleSectionTextAttributes'.
10/02/2014 AH
Fixed linkHtml support as it was calling the wrong named template and thus would not
render at all.
08/28/2014 AH
Adjusted time zone in formatDateTime representation so it just displays as-is when available. The number2name conversion,
e.g. PST or CET, would fail part of the year due to daylight savings
Implemented minimal mitigation for the security risk in rendering iframes for an arbritrary reference/@value
Note that this cda.xsl does not copy arbritrary attributes from section text. The
noted risk on calling external images thereby sending HTTP Referer URL is not mitigated
05/30/2013 AH
Made parameters out of font-family and font-sizes for the main font, h1-h6, and footers
Font-sizes are now all in points rather than pixels and points so more reliable in
rendering
Fixed getLocalizedString so it now does a lowercase comparison of the language
Added German translations for Table of Contents and Show/Hide revisions
05/29/2013 AH
Internet Explorer update: disabled the use of textEncoding, otherwise it would not render
Fixed font-size problem for Internet Explorer 8 - it doesn't inherit size in td tags
Fixed table of contents problem for Internet Explorer 8 - wouldn't open
Fixed #documentfooter style
Pulled bgcolor in the header and footer part into CSS so it may be overridden
05/28/2013 AH
Redesigned the setup. Now has three main divs.
#documentheader contains basic Patient and Author info
#documentbody contains section content
#documentfooter contains all relevant CDA header info
Updated for CDA release 3 as of Ballot May 2013. Includes datatypes awareness in alle
relevant places This update is largely about feature parity
Added <oXygen/> style documentation tags to facilitate HTML documentation
05/22/2013 AH
Added parameter for external css if so desired
06/28/2011 AH
Improved show-id by diplaying nullFlavor where applicable
05/31/2011 AH
Improved show-code to return translated codes, and finally the original code if originalText
and @displayName fail
Improved label on bottom participant to include translated assignedEntity/code if
available
Improved readability of participant/assignedEntity
05/30/2011 AH
Participant codes are now displayed by default instead of only when the name is omitted
Fixed translation of patientIdLong, by using the literal string instead treating it
as a node
Improved title on ids in fixed top header by adding a newline between multiple ids
Changed behavior of "Waarschuwingen" and "Behandelaanwijzigingen" to display "Er zijn
geen ..." if they are not applicable, instead of showing nothing
Changed "Behandelaanwijzingen into "Behandelrestricties"
05/03/2011 AH
Added language file and a template getLocalizedString to deal with it
Added parameter textLang to feed the desired language. Does not work with just a browser,
so textLang needs to be set in any environment
Replaced all current text in the stylesheet with calls to getLocalizedString
Improved layout of page so there's now a fixed header. Shrunk the TOC into a button
with hover to open so it doesn't always take up all screen space. The layout is enforced
using div with an id To avoid lots of scrolling in the header area this part needed
to be predictable and small. All header info except recordTarget is now to the bottom
of the document Also the document title was made less big
Added support for every styleCode in CDA release 2, not just bold/italics/underline,
but also all list styles and e.g. Botrule
Added support for footnotes/footnoteRefs
Added support for multiple section authors (used to be just one, and support was bugged)
Added support for (multiple) section informants
Added support for section subject
Added support for @ID, @IDREF, @language, and all other style properties from CDA
release 2
Added support for the display of nonXMLBody with text/plain content
Added support for Narrative block <linkHtml/>
Added support for revisions. Deletions will get a strikethrough, Insertions an underline
and overline Both get a title saying 'delete' or 'insert'. This feature is off by
default, but above the TOC there's a toggle to switch revisions marks on or off. A
little Javascript was used for that.
Added confidentiality to the title of the document if present and other than N (Normal).
If someone took the effort to send the confidentiality it should be 'in your face'
as recipient.
Added support for multiple section authors (used to be just one, and support was bugged)
Added support for (multiple) section informants
Added support for section subject
Added a switch to diable Javascript in case the environment requires that
Improved support for data type II when there's only a root and no extension
Improved support for the author organization which not displayed
Improved support for telecom and addr use codes. Now supports multiples
Improved support for names. Now gets out every node, supporting mixed mode too.
Improved readability for the support for lists by combining the two templates
Improved support for observationMedia by removing the limitation of just gif and jpeg.
If the browser does not support a given type, then at least a question mark is displayed.
Before there was nothing
Improved support for observationMedia by adding the id (if available) to the alt and
title of the image
Added support for inline base64 images. HTML actually can deal with that too
Improved handling of addresses so it now walks through all nodes, support mixed content.
Also, the elements are now handled in the order of the instance and not just US order
Improved support for dates by including a language switch. Now just handles en-US
and nl-NL, but could handle more Likely more sophisticated support is in order, but
this works for our purposes while leaving US conventions intact
Improved handling of names, addresses and telecom. The templates gave incorrect results
for multiples of these, mixing the contents of the latter with the first. Added name
use code to the display of names if available.
Fixed the author string in the main document info. It used to '-', but is now "Author"
in any supported language
Produces a section title with at least an anchor based on relative position in the
document (for the Table of Contents), and a second anchor if the section has the @ID
tag
<xsl:template name="section-title"><a><xsl:if test="@ID"><xsl:attribute name="id"><xsl:value-of select="@ID"/></xsl:attribute></xsl:if><xsl:attribute name="name"><xsl:apply-templates select="." mode="getAnchorName"/></xsl:attribute></a><!--<xsl:if test="@ID">
<a name="{@ID}"/>
</xsl:if>--><h3><xsl:if test="hl7:code"><xsl:attribute name="title"><xsl:call-template name="show-code-set"><xsl:with-param name="in" select="hl7:code"/><xsl:with-param name="sep" select="', '"/></xsl:call-template></xsl:attribute></xsl:if><xsl:choose><xsl:when test="count(/hl7:ClinicalDocument/hl7:component/hl7:structuredBody/hl7:component[hl7:section]) > 1"><!-- Add link to go back to top if the document has more than one section, otherwise superfluous --><a href="#toc"><xsl:apply-templates select="." mode="getTitleName"/></a></xsl:when><xsl:otherwise><xsl:apply-templates select="." mode="getTitleName"/></xsl:otherwise></xsl:choose></h3></xsl:template>
Handle footnoteRef. Produces a superscript [n] where n is the occurence number of
this ref in the
whole document. Also adds a title with the first 50 characters of th footnote on the
number so you
don't have to navigate to the footnote and just continue to read.
Namespace
No namespace
Match
hl7:footnoteRef
Mode
#default
Import precedence
0
Source
<xsl:template match="hl7:footnoteRef"><xsl:variable name="idref" select="@IDREF"/><xsl:variable name="footNoteNum"><xsl:for-each select="//hl7:footnote"><xsl:if test="@ID = $idref"><xsl:value-of select="position()"/></xsl:if></xsl:for-each></xsl:variable><xsl:variable name="footNoteText"><xsl:copy-of select="//hl7:footnote[@ID = $idref]//text()"/></xsl:variable><sup><xsl:text>[</xsl:text><a href="#{$idref}"><!-- Render footnoteref with the first 50 characters of the text --><xsl:attribute name="title"><xsl:value-of select="substring($footNoteText, 1, 50)"/><xsl:if test="string-length($footNoteText) > 50"><xsl:text>...</xsl:text></xsl:if></xsl:attribute><xsl:value-of select="$footNoteNum"/></a><xsl:text>]</xsl:text></sup></xsl:template>
Handle RenderMultiMedia. This currently only handles GIF's and JPEG's. It could, however,
be extended
by including other image MIME types in the predicate and/or by generating <object>
or <applet>
tag with the correct params depending on the media type @ID =$imageRef referencedObject
Handle one line of birth/death/multiple birth data
Parameters
in
One element with the child elements birthTime, deceasedInd, deceasedTime, multipleBirthInd,
multipleBirthOrderNumber. Each of those is optional and may bein the V3 namespace
or in another namespace like sdtc
Retrieves a language dependant string from our language file such as a label based on a key. Returns string based on textLang, textLangDefault, the first two characters of the textLangDefault, e.g. 'en' in 'en-US' and finally
if all else fails just the key text.
Parameters
pre
Some text or space to prefix our string with
key
The key to find our text with
post
Some text like a colon or space to postfix our text with
Default language for retrieval of language dependant strings such as labels, e.g.
'en-US'. This is the fallback language in case the string is not available in the
actual language. See also textLang.
Actual language for retrieval of language dependant strings such as labels, e.g. 'en-US'.
Unless supplied, this is taken from the ClinicalDocument/language/@code attribute,
or in case that is not present from textlangDefault.
Currently unused. Unsupported by Internet Explorer. Text encoding to render the output
in. Defaults to UTF-8 which is fine for most environments. Could change into more
localized encodings such as cp-1252 (Windows Latin 1), iso-8859-1 (Latin 1), or shift-jis
(Japanese Kanji table))
Boolean value for whether the result document may contain JavaScript. Some environments
forbid the use of JavaScript. Without JavaScript, certain more dynamic features may
not work.
Absolute or relative URI to an external Cascading Stylesheet (CSS) file that contains
style attributes for custom markup, e.g. in the @styleCode attribute in Section.text
Determines if the document title and top level summary of header information (patient/guardian/author/encounter/documentationOf,
inFulfillmentOf) should be rendered. Defaults to "true", any other value is interpreted
as "do not render". Some systems may have a context around the rendering of the document
that would make rendering the header superfluous. Note that the footer, which may
be switched off separately contains everything that the header does and more.
Security parameter. When set to 'yes' limits the URIs to images (if any) to locally
attached images and/or images that are on the external-image-whitelist. When set to anything other than 'yes' also allows for arbritrary external images
(e.g. through http:// or https://). Default value is 'yes' which is considered defensive
against potential security risks that could stem from resources loaded from arbitrary
source.