Convert your FHIR JSON -> XML and back here. The CDA Book is sometimes listed for Kindle here and it is also SHIPPING from Amazon! See here for Errata.

Thursday, October 1, 2015


Yesterday I attended a meeting containing a blue ribbon panel of EHR and CDS standards geeks in a packed room at Children's Hospital, hosted by Josh Mandel, and attended by head FHIR chief Grahame Grieve.  Josh is probably the best example of a FHIR chief that we have in this country. His work on SMART is already being adopted by EHR systems and healthcare entities in this country. We talked about a new way to integrate clinical decision support into the EHR, which I'll describe below.

Essentially the idea is to have applications register with an EHR their desire to be notified at particular points in the provider workflow, and to request specific information be provided to them. Associated with the application registration are:

  1. The service URL to invoke: [base]/$cds-hook
  2. The identifier for the trigger event (e.g., medication-prescribe)
  3. An optional pre-fetch template to obtain data to pass to the service URL in addition to the resource associated with the trigger event.
The service will pass back zero or more "action cards" which can be used to tell the EHR the advice given by the CDS service.  The EHR can decide on how to integrate that advice into the physician workflow.  You can find more details on Josh's wiki for the project.

This is quite cool, and works well with existing patterns of CDS use.  
  1. Information action cards provide sort of an extended InfoButton capability.
  2. Other action cards fit well within patterns established by FHIR Care Provision (e.g., ReferralRequest and ProcedureRequest), MedicationOrder, and Workflow (e.g., Order, DeviceUseRequest, SupplyRequest, etc.).
  3. Still other action cards can integrate with a cloud-based or locally hosted HTTP service to provide additional user interaction, and be integrated into the EHR ala SMART kinds of interfaces.
  4. Yet other action cards (discussed in the meeting, but not yet described on Josh's wiki) might support other capabilities within the workflow, perhaps to address the CDS integration itself. One example of this we discussed at the meeting was that when a service is not covered by a payer (as determined by one service), going into another service that looks at determining medical necessity might not be needful).
A couple of comments come to my mind when looking at this:
  1. I'll bet I can find hundreds of trigger events and associated contexts for CDS from HL7 Version 2, Version 3, InfoButton, HITSP, IHE and other specifications.  This is more of a data mining exercise for trigger events than anything else.
  2. Separately, each trigger event may want to be associated with one or more principle resources that describe the data associated with the trigger event.  For example, for the medication-prescribe event listed above, the likely candidate would be MedicationOrder.
  3. The way that the pre-fetch template works is a quite generalizable mechanism that supports many different integrations.  
That last comment deserves a lot more expansion, because I think it is the keystone to advancement in many standards.

This mechanism generalizes specific templates for sending data for an integration.  For example, this is how IHE had previously integrated forms based data capture in the Request Form for Data Capture (RFD) profile, with the needs for specific data as described in the Clincial Research Document (CRD) profile.  A similar mechanism has been used by CDS implementors by providing recommendations based on the content of a Virtual Medical Records (VMR) delivered through a CCD document.  It would also work quite well to specify the data requirements for a quality measure. By "registering" the pre-fetch bundle with the EHR, the CDS system allows the "question" to come to the data (as we did for Query Health), and the EHR to decide (based on the policies of its organization) how to respond to this query.  

Fortunately, this meeting came at a time when both CDS and Clincial Quality Measures in FHIR are currently being discussed in HL7, and can so impact both of those activities prior to them becoming DSTUs.  I'll very likely be making this point next week at the working group meeting in Atlanta, but if I don't I can count on many of the luminaries in the room yesterday to also do so.

I was thrilled to be invited to this event, and am really grateful for Josh's continuing his past outstanding work.  He is clearly no "one-shot" wonder, and I look forward to his future contributions to the world of standards.


P.S. One of the values we have in the "slow-down" of ONC on the development of standards is the luxury of time to do things right, instead of against an arbitrary deadline.  That makes me hopeful that CDS, instead of being the unfindable Holy Grail of EHR integration, would instead become a commonplace mechanism for building the best EHR system one could imagine.

Tuesday, September 29, 2015

All the review in the world isn't as good as trying to implement a standard

I'm [back] in the midst of trying to create a C-CDA <--> FHIR translator.  I already know from experience that just looking at a specification won't tell you where the implementation issues might appear ... however, this current experience just serves as an additional reminder.

Some things I've discovered thus far in FHIR's DSTU 2: The Condition and AllergyIntolerance resources take a slightly different approach to capturing status.  Condition separates verification status (provisional, differential, confirmed, refuted, entered-in-error, and unknown) from clinical status (active, relapse, remission, and resolved).  However, AllergyIntolerance groups these together as (active, unconfirmed, confirmed, inactive, resolved, refuted and entered-in-error).  Note the similarity between these three lists.  It indicates that some subsequent harmonization may be needed.

I also noted that AllergyIntolerance simply has onset as a dateTime, whereas condition has dateTime, Age, Period, Range and string.  The onset dates of allergies are just as frequently reported with imprecise dates and times as conditions, perhaps even more so, another place where these two could converge just a little bit better.

That's why I keep on writing code, even if I never expect it to show up in product.


Friday, September 25, 2015

Developing Standards is like building a deck

... or any other complex project.  Except that all too often missing a deadline (especially in the prime years of Meaningful Use) is considered to be such a failure that shortcuts are often taken which can have a dramatic impact on quality.  I'd much rather do the job right than do it over.

I just recently had a deck put on my house, and it's about a month late (100% schedule overrun).  But I'm happy with the work that has been done. What were the delays?

Labor: Sometimes people simply weren't available (e.g., subcontractors for plumbing and electrical). When the electrician failed to show up the third time, I did the job myself in about 3 hours.  It was a small enough job that getting him to show up was difficult.  Fortunately, I could make do with my own skills.  In standards, this often happens when a specialist isn't available to review some critical work (as happened recently in some revisions to the Claims Attachments work).  The first problem is in understanding that you need a specialist, and the second is finding one who is available on your schedule, or adjusting your schedule.

At other times (especially during holidays), labor simply isn't available, and you have to deal with the down-time.  Or other higher priority work (to the laborers) gets in the way of your priorities.  Once again, you have to get the work done when the labor is available.

Materials: Sometimes the material runs out before the job does, and more needs to be acquired.  In standards development, we often aren't dependent on materials, but we are often dependent on either data, or other projects to provide materials that we need.  You either have to make do without, or take your best guess, or wait until the right stuff is there.  Frankly, I don't want a tri-colored deck with different planks, so I waited it out.  We did expedite the reorder, and sometimes there are ways that you can expedite the delivery of dependencies, for example, the DAF project needed some materials from FHIR DSTU 2 and CDA on FHIR, so they chipped in to help where applicable.

Review: We were at the mercy of the building inspector's schedule on the deck project, although I live in a small enough town that it usually meant a delay of only a day or two.  However, sometimes that messed up other schedules (I'm about a month behind on another project due to delays on the deck).  In the C-CDA 2.1 DSTU Update project, review was critical, and so we made sure to plan ahead for how long that would take, and I set aside that next week for my own review. Unfortunately, that's not always the case in other standards projects, and frankly, one of the problems with standards development is that we often don't know what will work until we try it.  This is a place where engineering is different from software development (which is still more art than science) [and standards development is very much like software development in many places].  DICOM has an excellent review process for its standards development, but it also induces delays that others would find difficult to accept.

Change orders, a.k.a. scope creep.  My electrical challenges were a result of a change order late in the project.  The electrician could have done most of the work anytime, with the final finish [installing the exterior fixture] taking no more than a half hour.  However, because I added this near the finish of the job, we were at the mercy of the electrician's schedule.  Having your scope nailed down well at the beginning if great, but when you don't, expect delays.  The Relevant and Pertinent project didn't originally have a short physician survey in its scope, but after project review, we decided that we needed to do it anyway.  That's caused several delays, but we aren't going to sacrifice on quality to make up for lost time.

In any project management, there's a triangle of resources, scope and quality.  One of your resources is time, and if you cannot afford to give up time, you may well be trading off quality or scope.  I'd much rather reduce scope and produce a high quality project, but even that is not always a possibility. All too often I've seen government contractors push to hit a schedule because either their lords and masters demand it, or because if they don't finish on time, they don't get paid for any additional time.

When you budget a project, you should always leave yourself a reserve (in time or money) to deal with change.  All too often, when we initiate a standards project, we don't allow for that.  I'm grateful my deck is finally done (or very near so, we are still waiting for the building inspector), and I'm also grateful that most of the projects that I've been involved with this year are similarly close or beyond the stage of being done.

Of course that means that I'm about ready to start the next set of projects, both at the house, and in HL7 and IHE.  IHE's call for proposals for PCC, ITI and QRPH went out a while back and that deadline is looming (tomorrow).  I'm presently working on a PSS in Clinical Decision Support to propose adoption of an IHE profile for Guideline Appropriate Ordering as a FHIR Profile in HL7. The reward as always for a job well done... is another job.  That's just as true in standards as it is in contracting.


Wednesday, September 23, 2015

A whirlwind tour on FHIR

Fire Tornado by Karen O'D
I think I just finally solidified my travel in November.  It starts off with three days in Oakbrook, IL where I will be spending the first day (November 11th) training IHE developers about FHIR.   That will be followed by two days of profile proposal technical committee review, in which I expect to see several focusing on using FHIR to implement interoperability in various use cases.

Following that I head off to AMIA for several days where I expect to spend at least some time in sessions discussing FHIR, including various panels, a paper, several posters (Monday 5pm), and a system demonstration.  There will of course be other things attracting my interest as well.

I head out mid-day on Tuesday though, so I won't be able to see everything on FHIR because I'll be heading off to FHIR Developer days in Amsterdam.  This is the second (annual) edition of this event in Amsterdam.  I'll be talking about how IHE Patient Care Coordination developed two FHIR profile proposals, one of which (GAO) we are hoping to ballot through HL7 adoption process (See chapter 18 of the HL7 GOM).

I expect to be thoroughly exhausted when I'm done. But that is what happens to your fuel when you put your FHIR into the whirlwind.

   -- Keith

P.S.  The last bullet on my "What is FHIR?" slide says "A source of bad puns."  I would also add, and good marketing.

Monday, September 21, 2015

A long long time ago ... (XML from Word part 2)

To begin your unflattening, you will have to prepare a piece of data to explain what the structure of the final output needs to look like.  If you are simply unflattening HTML or Word using heading numbers, this is fairly straightforward.  If your document has a good bit more style and structure, you may need to do a bit more work.  Assuming you have a good XML Editor (just about any decent one can do this next step), you should be able to produce an XML Schema from a sample XML document.  The schema will suck, looking something like this:

<xs:schema xmlns:xs="" elementFormDefault="qualified">
  <xs:element name="body">
      <xs:choice maxOccurs="unbounded">
        <xs:element ref="p"/>
        <xs:element ref="h1"/>
        <xs:element ref="h2"/>
        <xs:element ref="h3"/>
        <xs:element ref="h4"/>
        <xs:element ref="h5"/>
        <xs:element ref="h6"/>

Take the table of <xs:element> names and put them into another file somewhere, and add attributes that indicate the nesting level for each element, like this:
  <element ref="body" level="0"/>
  <element ref="h1" level="1"/>
  <element ref="h2" level="2"/>    
  <element ref="h3" level="3"/>    
  <element ref="h4" level="4"/>    
  <element ref="h6" level="5"/>    
  <element ref="h6" level="6"/>    
  <element ref="p" level="7"/>    
This table basically assigns a nesting level (or precedence) to each element name, so that you (or software) can figure out the nesting level.

Where the magic comes in is how I use it next to apply the structure.  You can do this sort of processing of a list of elements really easily in Java or JavaScript or C++ if you understand how to write parser for a language whose parse tree can be described with operator precedence.  But if you want to do this using XSLT, you'll need a lot of research, or a really twisted brain to figure this out. Fortunately for you, I just spent the last week in Portland, so my brain is already twisted after three days of Evidence Based Medicine at OHSU ;-).

To make this stylesheet work, you are going to need to run two passes over your XML (or have two separate stylesheets.  The first pass simply adds an attribute to each element that assigns it the precedence level from the previous document, and then turns this result tree into a node-set (via the EXSLT node-set extension function) and sends it to the next phase.

<xsl:stylesheet xmlns:xsl=""
  extension-element-prefixes="exslt" version="1.0">

  <xsl:output indent="yes" method="xml"/>
  <xsl:variable name="prec" select="document('precTable.xml')"/>

  <xsl:template match="/">
    <xsl:variable name="pass1">
        <xsl:for-each select="content/*">
            <xsl:copy-of select="@*"/>
            <xsl:attribute name="text">
              <xsl:value-of select="."/>
            <xsl:attribute name="_level">
              <xsl:value-of select="$prec/table/element[@ref=local-name(current())]/@level"  />
    <xsl:apply-templates select="exslt:node-set($pass1)/content/Tabular" mode="process"/>

What this does is basically run through each element child of <content> and add an _level attribute to that element.  It gets the element by finding it in the /table/element list, looking for one whose @ref attribute matches the name of the element.  Why do I do this step?  Locality of reference for the next ugly bit.  Basically, this is an optimization that makes the next optimization really shine.  My file has 35000 lines.  The algorithm that you might figure out for yourself in XSLT (if you can twist your brain around it) runs on the order of O(n3).  On my first attempt at an algorithm, I was looking for the children of each parent.  That lookup that I preprocess would be needed 42 trillion times if not preprocessed, and it doesn't run quickly since it is essentially a linear search.  Even with the optimized version below, this lookup is best not repeated if you can precompute it, so I do.

The algorithm I finally figured out after failing several times runs a lot faster. I estimate it is around O(n log n). I owe Jeni Tennison a beer if I ever see her again (and Steve Meunch), because I wouldn't have figured it out were it not for her post on his algorithm.

What I realized was that each element in the file has can have unique key computed which identifies its parent, and that key can be expressed in XSLT as the unique identifier of the first preceding sibling of that element whose level in the hierarchy is lower that then of the element.  You declare this in XSLT using the following line:

  <xsl:key name="parent" match="*"
    use="generate-id(preceding-sibling::*[@_level &lt; current()/@_level][1])"/>

Then, these next two templates do the magic restructuring:

  <xsl:template match="/" mode="process">
      <xsl:apply-templates select="/content/*[1]"/>

  <xsl:template match="*" mode="process">
      <xsl:copy-of select="@*[local-name()!='_level']"/>
      <xsl:apply-templates mode="process" select="key('parent',generate-id())"/>

That's a remarkably short bit of code for the magic it performs!  The first template simply kicks things off.  For each element the next template processes, it makes a copy of the XML (using xsl:copy and xsl:copy-of, and then inserts the content of all of the nodes which claim (through the parent) key to be its direct children.  If you instrument the output with <xsl:message> elements as I did when I first ran it, you'll see a BIG pause (at least if you run a 35000 line file through it), and then magically, everything will come out in a great big WHAM!

What is happening here is that first pause is the indexing stage, where the XSL process goes: "OK, he really does mean to use the parent key, I better go make an index." (Yes, I tend to anthropomorphize software).  Then it identifies every node (all 35000) of them, and executes the XPath expression in the use attribute.

generate-id(preceding-sibling::*[@_level &lt; current()/@_level][1])

That XPath expression says: for each preceding child whose level is less than mine, take the first one. Most XSLT processors are smart about any expression which ends in the pattern [number], especially when number is 1, or the expression last().  That usually means that the expression can be computed more efficiently and short circuited once the first item is found.  The indexing step likely has average case execution time of O(n log n).  Each element generates an index key.  The elements are found in O(n).  At the deepest layer, their are O(n) nodes, and it takes a constant time to find their parent. Their are O(log(n)) layers in the tree, and it takes approximately the same amount of time to compute their parent(less actually for balanced trees of breadth X [each node containing X children]).  The recursive processing step is O(n) once the index is precomputed. Putting all that together give O(n log n), which finally made this work without a week of processing time.

The real trick here was instead of trying to find the children of each node, turning the problem on its head and finding the parent of each child.  That is what makes the whole algorithm simple.

How does this apply to standards?  The file I was processing was a vocabulary table written in a giant Word document.

Saturday, September 19, 2015

A long long time ago ... (XML from Word)

A very long time ago (more than 15 years), I worked on a product that allowed you to take inputs from various formats and restructure them as XML (or SGML).  It was a very useful tool, and made it very easy to convert Word documents to XML, especially when those documents didn't have a great deal of nested structure.

This is fairly common: Word, HTML and many other file formats don't really handle heading level nesting the way you would output information in XML.  When you wind up with a document that has a lot of "structural" information it its styles, getting that structural information represented in your XML can be very handy.  But it can be a royal PITA to get that structure back from the Word document.

I used to do this with a Word macro, but these days I find it easier to extract the styled information into an HTML file.  Use the "Save As..." and then use Filtered HTML as your output format, and what you will get is pretty decent HTML which won't contain a lot of Word specific gunge.  Your next step will be to remove all the stupid content in between <o:p> and </o:p> tags that Word inserts to support empty paragraph and whitespace handling in various versions of the IE browser (from about 5.X on they changed various things that needed special HTML handling for each version).

After you've done that, you need to tidy up the HTML so that it is proper XHTML to begin the final phase of restructuring.  To do this, I use jtidy, the Java implementation of Dave Ragget's Tidy program.  The command line is fairly simple:

java -jar jtidy.jar -m -asxml filename

This command will read filename, cleanup the HTML and turn it into XHTML (-asxml), and then modify (-m) to original file to contain the cleaned up output.

So what was
<p class=foo><span class=bar>Stuff<br></span></p> 
<p class='foo'><span class='bar'>Stuff<br/></span></p> 
This will make your life a lot easier. In the next two steps.

The next step simply uses the class attribute as the element name in the output.  So all tags are now rewritten using the class names (which were originally your style names in Word).  Here's the stylesheet to start XML-ifying the XHTML.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="" 
  <xsl:output method="xml" indent="yes"/>
  <xsl:strip-space elements="*"/>
  <xsl:template match="html:head"/>
  <xsl:template match="html:body">
  <xsl:template match="html:*">
      <xsl:when test="contains('1234567890',substring(@class,1,1))">
        <xsl:element name='_{@class}'>
        <xsl:element name='{@class}'>
  <xsl:template match="html:a">
    <xsl:attribute name="id">
      <xsl:value-of select="@id"/>

Now, you still have this flattened XML.  What you need to do is "unflatten" it, and I'll explain how to do that in my next post.

Monday, September 14, 2015

Code Generators: A love hate relationship

Some of my favorite projects have involved code generators.  I once wrote an LL(1) parser generator which processed SGML DTDs with some added stuff to make some great looking output from SGML.  Another time I took the XHTML from the IHE Wiki and ran it through a transform which then generated code which would output conforming IHE PCC Sections according to the PCC Technical framework.

My present work involves transforming from CDA and CCDA to FHIR and back.  To do that, I'm annotating the output from Trifolia with statements that express how to do the mapping.  Then my code generator essentially writes the transform from the CCDA entries to the appropriate FHIR output (Document, sections and narrative transforms I wrote by hand.  These are the scaffolding upon which my code generator operates from, and I didn't need to have that build automated.)

What I love about code generators is that once you get them right, the code they produce is inevitably correct.  And since the code generator can produce a LOT of code from a large input, this can be incredibly valuable from a software development perspective.

What I hate about code generators is that "ONCE you get them right" part.  Doing that is tricky, and a small change can also be very damaging.  Refactoring a code generator to get yourself out of a design dead-end is like threading a maze blind-folded sometimes.  And the wrong fix on a tiny bug can break TONs of code. However, once you finally get it right, the code is often nearly rock solid. After all, what the computer does really well is repetition.

Code generators are also especially difficult when the language you are writing your code generator is the same as what it will be producing.  Going from XSLT to JavaScript (or vice versa) is a heck of a lot easier than XSLT to XSLT or JavaScript to JavaScript. One challenge is that the levels of escaping you have to go through to ensure the correct output syntax are a pain.  Another is that you have to keep two different execution contexts in your head: The one you are writing your code generator in, and the one that it is writing code in.  I find myself wondering why a variable I clearly declared in one context doesn't exist in the other until I start looking in the right place.  That's not a problem when I have execution contexts in two different languages (var x =0; is so much different from <variable name="x">0<variable>).

What I also love about code generators though, is the challenge they provide, and the satisfaction that they do a tremendous amount of work that I couldn't have done by coding manually.

One of the great things about FHIR is its almost recursive relationship with itself (sort of like writing an XSLT to generate an XSLT, something only a true Geek could enjoy).  The fact that Conformance OperationDefinition, and SearchParameter resources exist to define how a FHIR server works is very comforting to me.  It means that I can stay within the same context when trying to do several things at once (as is often the case with Interoperability).  However, I think my favorite two "recursive" resources in FHIR are ImplementationGuide and TestScript.

Windows NT developers at Microsoft years ago, used to talk about "eating your own dog-food", referring to the fact that they had to use the OS they were building to build the OS that they were building, as they built it.  Well, FHIR is doing the same thing, and starting to develop the necessary resources to build the resources that will build the standard.

It's something that only a Geek could love from an aesthetic viewpoint.  From an outcomes viewpoint, I think the implementers of FHIR and the users of systems that implement it will love it too.  Because once you get it RIGHT, the code rocks.