PCC HowToWriteCDALevel3Templates

From IHE Wiki
(Redirected from PCC HowToWriteCDATemplates)
Jump to: navigation, search

The source document for this page can be found here:


In order to represent machine processable (or Level 3) data in CDA Release 2.0, an implementation generates entry elements that appear within various section elements of the ClinicalDocument. These entries use the observation, regionOfInterest, observationMedia, substanceAdministration, supply, procedure, encounter, organizer, and act elements found in the CDA Schema.

While CDA implementers can easily create implementations that use (schema) valid CDA representations of the clinical information, these implementations will not easily interoperate with other HL7 Version 3 specifications unless some care is taken in the specification of the CDA XML that results. The main reason for this is that the CDA model is very broad, encompassing, as it must, a wide variety of information requirements covering a large set of domains. Furthermore, the CDA model includes an early version of the Clinical Statement pattern upon which many HL7 Version 3 specifications are based (e.g., Patient Care Structures, Pharmacy, Laboratory). There are some variances between the CDA model and the current Clinical Statement pattern. In addition, each domain is permitted to extend and modify the Clinical Statement pattern to suite the requirements of the domain. This introduces variances between the domain specifications and the CDA. While many of these can be overcome by transformation, the ultimate goal of any implementer is to reduce the amount of work they have to do when transferring information from one source to another.

The purpose of this document is to describe the process has been used within the IHE Patient Care Coordination Technical Committee to produce Level 3 XML representations of structured information that is compatible with the CDA Release 2.0 schema, and which also meets many of the requirements of specific domain models.

This process was developed mostly ad-hoc, over a three day face-to-face IHE PCC Technical Committee meeting. Using it, I and others have been able to successfully produce CDA representations of level 3 information for a variety of data sets, including problems, allergies, and medications.

I would like to thank some Version 3 experts, including Dan Russler and Vassil Peytchev, who greatly assisted in this work, and Lawrence McKnight, a soon to be Version 3 expert who provided many of the initial examples that were used in the initial development of the IHE PCC Medications level 3 encoding.


Obtain a copy of the CDA Normative Edition Web Site. This is essential, as it contains the normative schemas, the CDA Hierarchical Descriptor, and the CDA R-MIM.

Learn how to read an R-MIM. Unfortunately, very few XML examples exist within any given domain for the different messages that need to be transmitted. If this were otherwise, you could start there, but since you cannot, you will need to start with the R-MIM or D-MIM diagrams for the domain.

Understand the HL7 data structures, and the XML Implementation Technology Specification. Without this knowledge, you will not be able to read an R-MIM (see above).

Next, obtain a clinically complete set of examples of the thing that you wish to encode (e.g., various labs, or different kinds of prescriptions, et cetera). Ensure that you have covered common cases (e.g., normal prescriptions), and as many as possible edge cases (e.g., split dosing, tapered dosing, compound medications, et cetera).

If you are a software engineer, have a physician handy, and if a physician, have a software engineer handy. I've found very few people with sufficient skills to do this by themselves.

Next, print out, or have otherwise available, the relevant R-MIM or D-MIM from the HL7 Version 3 domain specification that you wish to use. Do the same for the CDA and Clinical Statement pattern.

The Process

<entry> You will be creating one or more entries containing an element derived from the act class. Work on a single entry at a time. You might find it easier to work from the top-down, or bottom-up. If there are common features to your entries, then working from the bottom-up, at least for those, is advisable.

Now, look at your MIM. Find the thing (or things) you want to represent in the CDA document. Determine what kind of CDA element it should be, from the following list:

  • observation
  • substanceAdministration
  • supply
  • procedure
  • organizer
  • act
  • regionOfInterest
  • observationMedia

Now, find the appropriate definition for this element in the CDA schema. Open up a text file, and create a "maximal" element that is valid according to the CDA.. Let's assume for example that you chose observation.

I've pulled out the observation element in figure N below. With about five minutes of text editing, I took the schema definitions, and turned them into the start of my observation.

<observation classCode='' moodCode=''>
	<!-- Attributes: -->
	<templateId extension='' root=''/>*
	<id extension='' root=''/>*
	<code code='' displayName='' codeSystem='' codeSystemName='' />
	<statusCode code=''/>?
	<effectiveTime value=''>
		<high value=''/>
		<low value=''/>
	<priorityCode code='' displayName='' codeSystem='' codeSystemName=''/>?
	<repeatNumber value=''>
		<high value=''/>
		<low value=''/>
	<languageCode code=''/>?
	<value xsi:type=''  value=''/>*
	<interpretationCode code='' displayName='' codeSystem='' codeSystemName=''/>*
	<methodCode code='' displayName='' codeSystem='' codeSystemName=''/>*
	<targetSiteCode code='' displayName='' codeSystem='' codeSystemName=''/>*
	<!-- Participations: -->
	<!-- Relations: -->

There are already of couple of things that you can see.

  1. I've added empty valued attributes for codes, identifiers and values for the types that I recognize (e.g., CD,CE for codes), value for time, numbers, and I've also added a high/low pair for any interval. If the type is ANY, add an xsi:type entry to remind yourself to pick one later.
  2. I add in empty attributes for classCode and moodCode.
  3. I've got comments to separate attributes, participations, and relationships.
  4. I've added simple text notations after each element to indicate its cardinality:
    1.  ? for optional elements
    2. * for optional repeating elements
    3. + for repeating elements

Now I have something to start with, that reflects everything the CDA could support. Next I have to figure out:

  • What I can get rid of (what is in the CDA model, but not in the domain model),
  • What is missing (what is in the domain model but not supported by CDA),
  • How to support the missing content (if it is really necessary).

Take this step by step, first starting with the attributes.


Delete realmCode, languageCode and typeId. These are mostly infrastructure, and don't usually get in the way .

Next, assign a templateId to this particular kind of entry you are creating. You can just pick a value, or find a system that works for you. One system that's pretty good (but not perfect ), is to use the RMIM identifier and the clone name. Assume that later you will obtain an OID for all the identifiers you assign.

Pull out your domain model diagram.

Go through each RIM attribute, and fix up the cardinalities in your sample XML.

If you found a RIM attribute that exists in your model, but doesn't exist in the sample XML, this is a potential problem. Insert it back into the XML, but use a different namespace for the element. These are potential extensions.

If you didn't find the RIM attribute in your model, and it isn't required in the sample XML, delete it. If it is, you have a small problem. If it's null-able, then tell people to use a flavor of null with it. If not, and there is no reasonable fixed value that can be assigned, you have a larger problem. I haven't run into any of these yet. If you do, talk to the domain experts and committee chairs, and tell them what the issue is.

Advice on Specific types or elements

If the domain model restricts this, put in the restricted code value or the value set, e.g.: classCode='ACT|OBS'

If the domain model restricts this, put in the restricted code value or the value set, e.g., moodCode='RQO|EVN'.

Require at least one, and let it identify the instance.

If there is one, follow this model: <text><reference value='#PointerBackIntoTheCDANarrative'/></text>

Give guidance on what this value should point to in the CDA document.

Or, if you really don't care what piece of text in the CDA narrative that this entry is talking about, then delete <text>.

Please don't tell people to duplicate the text that is already in the CDA document. Now you've got the same text in two places. This causes implementation problems because there is now way to ensure that they match up!

The code is the query, the value is the answer to the query. See CD and CE below.

The value is the answer to the query, the code is the query.

For any element that is an interval, ask yourself if you need all the power intervals support, or if you can get away with high/low or single valued representation. If you can limit yourself to just high/low or single value, do so.

Can you pick a single type? If so, do so, and specify it in the xsi:type attribute. If you have a small list, then use that.

If the domain model restricts the coding system, put in the codeSystemName. At the end of this process, you will go back and fill in OIDs.

If the implementation will reasonably be able to determine what part of the narrative that the code applies to, add an originalText element to the CD or CE based element .

<code	code='' displayName='' codeSystem=''
	<originalText mediaType='text/xml'
		><reference value='#IDOfThingToWhichThisCodeApplies'/


Do the same thing for participations that you did for attributes with regard to cardinality. You will most likely find mismatches, as CDA only supports the following:


But the Clinical Statement pattern also includes


Furthermore, the domain model may have included other participations (e.g., informationRecipient).

First of all, recordTarget should be in all cases the same as the recordTarget of the Clinical Document, and so, should not be required.

If the participant you have identified doesn't exist in the CDA clinical statement model, the next question to ask is whether it will always be the same as the similarly named participant in the Clinical Document header. If the answer is yes, then you don't need that participant, as it can be deduced (conductionInd='true') from the context in which the entry appears.

If the answer is no, see if you can map the very specifically identified participant from your domain model into the CDA participant element. If you can, great, if not, you need to talk to an expert. I haven't had this problem yet.


The nice thing here is that there isn't any relationship that you won't be able to partially model in the CDA. The reason is that every act in CDA supports multiple occurrences of the entryRelationship element, which can contain any act class.

The difficulty arises when you need a RIM attribute on the relation that is other than contextConductionInd, typeCode, sequenceNumber, or seperatableInd.

In these cases, you need to either: omit the attribute, omit the participant altogether, or add an extension.

Inside the entryRelationship element, put the act, observation, et cetera, that you need to refer to.

OK, now you have a new element derived from the act class that you need to map into CDA. Put it on your list of work, and start the process over again with this one .