CDA R2 Stylesheet
The CDA Release 2.0 and 2.1 publications come with an informative stylesheet based on XSLT 1.0. The stylesheet is maintained under responsibility of the Structured Documents Workgroup. The download location is through the GForge StrucDoc project.
The intent of the stylesheet is to offer an example of how to render a CDA document. It does this by rendering XHTML 1.0 Strict with the following information:
- a summary of the header for the most important context, i.e. patient, author, encounter, documentationOf and inFulFillmentOf
- the section code, title and text (human readable text)
- the full header information
No CDA level 3, i.e. entry level information, is rendered.
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
The CDA XSL has been tested to work with Saxon-PE and major browsers. Effort is put in to make rendering friendly for visually impaired people, based on the American Foundation for the Blind Section 508. Effort has been put in to make the document friendly for screen and for print.
The CDA XSL is a sample rendering and should be used in that fashion without warranty or guarantees of suitability for a particular purpose.
The CDA XSL contains at minimum two files that you need accessible for CDA documents to call or for programmatic access (see #Manual)
- cda.xsl - main logic
- cda_l10n.xml - location file containing translations for terms
There are multiple ways to apply the stylesheet. If you have files on disk or on a webserver for a web browser to consume, you need a hint for the web browser how to render to document. This hint is called a processing instruction and needs to be inserted before the
<?xml-stylesheet type="text/xsl" href="cda.xsl"?>
or with an absolute path:
<?xml-stylesheet type="text/xsl" href="http://example.org/cda/cda.xsl"?>
The web browser needs to be able to access the relative or absolute location of the stylesheet. For security reasons, you probably want that location to be inside your own environment.
Although the stylesheet supports many parameters, these are not configurable from a browser. If you need a different value for a stylesheet parameter than the default you can either update the default in the stylesheet, or run the stylesheet programmatically e.g. using Saxon-PE. If you update the defaults in the stylesheet, you might have a harder time updating the stylesheet if the base receives updates that you want in your environment too.
Running the stylesheet programmatically could be done in any environment that supports XSLT 1.0. The major implementations of XSLT are Saxon, libxslt and Xalan. Example command line call for Saxon where the parameter for rendering the header is set to false could be:
java -jar ../lib/saxon-9/saxon9.jar -s:cda-example.xml -xsl:cda.xsl -o:cda-example.html dohtmlheader=false mask-ids=2.16.840.1.113883.4.1
What this says:
- Run java, with the saxon9.jar file, to transform input file cda-example.xml, using stylesheet cda.xsl, to output file cda-example.html, without rendering the header info, and mask any patient ID with root 2.16.840.1.113883.4.1 (US SSN)
One of the core features of the updates to the stylesheet is localization or l10n. The original stylesheet has traditionally been US English, but the CDA is used all over the world and that means that applicability for other languages makes sense. The language is relevant in finding labels for things like "Patient ID" or "Date of birth", but also for structural attributes like classCode/typeCode/moodCode and NullFlavors. The language strings have been externalized into a separate xml file called cda-l10n.xml. The process works as follows:
- Determine language based on ClinicalDocument/languageCode/@code, unless override is done through parameter textLang -- expected format is 2 char language code from ISO639, followed by a hyphen and a 2 char country code from ISO3166, e.g. en-US. All will be lower-cased before use.
- For any label check if there is a translation element in cda-l10n.xml
- check if requested language is available
- check if match based on the first 2 character language code is available, e.g. en in en-US
- check if match based on the value of parameter textLangDefault is available, normally en-US
- check if match based on the first 2 character language code of parameter textLangDefault is available, e.g. en in en-US
- Finally if all else fails, return key as label
Adding support for a new language
Add a line like this in the languageList element at the top of the document:
<language description="Dutch (Netherlands)" lang="nl-nl"/>
Add new strings to existing translation elements as needed.
Adding a new string to an existing translation element
If the en-US term is sufficient for your language too: you do not need to list it in the language file. Add a line like this in the appropriate translation element:
Note that the value for attribute lang needs to exist in the listing of languages at the top of the file.
Adding a new translation element
This is only relevant when certain vocabulary or a certain identifier OID is in advertently not supported. Other strings could only occur if you are updating the stylesheet itself. Add a translation element like this:
<translation key="myKey"> <comment>Label: my comment in free text</comment> <value lang="en-us">Patient</value> <value lang="nl-nl">Patiënt</value> </translation>
Make sure that you en-US covered at the very least. Other languages as you see fit.
The stylesheet supports many way to parametrize.
- XSLT 1.0 does not have date function, so we need something to compare against e.g. to get someones age
- Default: /hl7:ClinicalDocument/hl7:effectiveTime/@value
- Vocabulary file containing language dependant strings such as labels
- Default: cda_l10n.xml
- 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.
- Default: en-US
- 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.
- Default /hl7:ClinicalDocument/hl7:languageCode/@code or if missing the value of $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))
- Default: utf-8
- Default: true
- 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
- Default: none
- Determines the font family for the whole document unless overruled somewhere
- Default: Verdana, Tahoma, sans-serif
- Determines the font size for all text unless otherwise specified, and is the base value for other font sizes
- Default: 9pt
- Determines the font size for text in the h1 tag
- Defaults to font-size-main + 3
- Determines the font size for text in the h2 tag
- Defaults to font-size-main + 2
- Determines the font size for text in the h3 tag
- Defaults to font-size-main + 1
- Determines the font size for text in the h4 tag
- Defaults to font-size-main
- Determines the font size for text in the h5 tag
- Defaults to font-size-main
- Determines the font size for text in the h6 tag
- Defaults to font-size-main
- Determines the font size for text in footnotes
- Defaults to font-size-main - 1
- Determines the background-color, as any legal hex, rgb or named color, for header like table elements, e.g. th tags
- Defaults to "LightGrey"
- Determines the background-color, as any legal hex, rgb or named color, for body like table elements, e.g. td tags, defaults to "#f2f2f2".
- Defaults to "#f2f2f2"
- 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.
- Default: true
- Determines if the document footer containing a listing of everything in the CDA Header 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 footer superfluous, or just want to concentrate on document contents.
- Default: true
- Determines depth of table of contents menu at the top of the document. Default is 1, which means just head section. Max is 3 which is head section + 2 levels (if any)
- Default: 3
- Security parameter. When a vertical bar separated list of URI prefixes, such as "http://www.example.com|https://www.example.com"
- Default: none
- 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.
- Default: yes
- Privacy parameter. Accepts a comma separated list of patient ID root values (normally OID's). When a patient ID is encountered with a root value in this list, then the rendering of the extension will be xxx-xxx-xxx regardless of what the actual value is. This is useful to prevent public display of for example the US SSN. Default is to render any ID as it occurs in the document. Note that this setting only affects human rendering and that it does not affect automated processing of the underlying document. If the same value also occurs in the skip-ids list, then that takes precedence.
- Privacy parameter. Accepts a comma separated list of patient ID root values (normally OID's). When a patient ID is encountered with a root value in this list, then the rendering of this ID will be skipped. This is useful to prevent public display of for example the US SSN. Default is to render any ID as it occurs in the document. Note that this setting only affects human rendering and that it does not affect automated processing of the underlying document.
The stylesheet is the cumulative work of several developers; the most significant prior milestones were the foundation work from Lantana Group, HL7 Germany and Finland (Tyylitiedosto) and HL7 US (Calvin Beebe), and the presentation approach from Tony Schaller, medshare GmbH provided at IHIC 2009.