Feb 032015
 

So I wanted to show how to map an HL7 message.
Here is the schema view:

Here is a collapsed view of the data:

Now you can’t simply use the mapping functiods to map it straight across, the sequence groups ‘appear’ to indicate what you think is a structure, however, the resulting XML from the BTAHL7 pipeline component creates a ‘flat’ structure.

So we are going to create custom XSL and going to map straight across, input to output. So I created the map and drew lines across to get the initial xsl structure defined.

<?xml version="1.0" encoding="UTF-16"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                xmlns:msxsl="urn:schemas-microsoft-com:xslt" 
                xmlns:var="http://schemas.microsoft.com/BizTalk/2003/var" 
                exclude-result-prefixes="msxsl var" version="1.0" 
                xmlns:ns0="http://stottcreations.com/HealthCare/HL7/2X/2.5/Segments" 
                xmlns:ns2="http://stottcreations.com/HealthCare/HL7/2X/2.5/Tables" 
                xmlns:ns3="http://stottcreations.com/HealthCare/HL7/2X/2.5/DataTypes" 
                xmlns:ns1="http://stottcreations.com/HealthCare/HL7/2X">
  <xsl:output omit-xml-declaration="yes" method="xml" version="1.0" />
  <xsl:template match="/">
    <xsl:apply-templates select="/ns1:ORU_R01_25_GLO_DEF" />
  </xsl:template>
  <xsl:template match="/ns1:ORU_R01_25_GLO_DEF">
    <ns1:ORU_R01_25_GLO_DEF>
      <xsl:value-of select="./text()" />
    </ns1:ORU_R01_25_GLO_DEF>
  </xsl:template>
</xsl:stylesheet>

So we need to start mapping the OBR segment: so let’s create a template for it.

    <ns1:ORU_R01_25_GLO_DEF>
      <xsl:apply-templates select="OBR_ObservationRequest"/>
    </ns1:ORU_R01_25_GLO_DEF>

Now in the OBR template we need to set an achor (since it is a flat structure) of the OBR1SetIdObr/text())

  <xsl:template match="OBR_ObservationRequest">
    <xsl:variable name="Anchor" select="OBR_1_SetIdObr/text()"/>

Now we actually start creating the OBR segment

    <OBR_ObservationRequest>
      <xsl:copy-of select="./@*" />
      <xsl:copy-of select="./*" />
    </OBR_ObservationRequest>

Now, we need to map any NTE segment, following the OBR Segment

    <xsl:for-each select="following-sibling::NTE_NotesAndComments[preceding-sibling::OBR_ObservationRequest[1]/OBR_1_SetIdObr/text()=$Anchor]">
      <NTE_NotesAndComments>
        <xsl:copy-of select="./@*" />
        <xsl:copy-of select="./*" />
      </NTE_NotesAndComments>
    </xsl:for-each>

And we need to map any OBX segment following the OBR Segment also

    <xsl:for-each select="following-sibling::OBX_ObservationResult[preceding-sibling::OBR_ObservationRequest[1]/OBR_1_SetIdObr/text()=$Anchor]">
      <OBX_ObservationResult>
        <xsl:copy-of select="./@*" />
        <xsl:copy-of select="./*" />
      </OBX_ObservationResult>
    </xsl:for-each>

The entire xsl is here:

<?xml version="1.0" encoding="UTF-16"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                xmlns:msxsl="urn:schemas-microsoft-com:xslt" 
                xmlns:var="http://schemas.microsoft.com/BizTalk/2003/var" 
                exclude-result-prefixes="msxsl var" 
                version="1.0" xmlns:ns1="http://stottcreations.com/HealthCare/HL7/2X" 
                xmlns:ns0="http://stottcreations.com/HealthCare/HL7/2X/2.5/Segments">
  <xsl:output omit-xml-declaration="yes" method="xml" version="1.0" indent="yes" />
  <xsl:template match="/">
    <xsl:apply-templates select="/ns1:ORU_R01_25_GLO_DEF" />
  </xsl:template>
  <xsl:template match="/ns1:ORU_R01_25_GLO_DEF">
    <ns1:ORU_R01_25_GLO_DEF>
      <xsl:apply-templates select="OBR_ObservationRequest"/>
    </ns1:ORU_R01_25_GLO_DEF>
  </xsl:template>
  <xsl:template match="OBR_ObservationRequest">
    <xsl:variable name="Anchor" select="OBR_1_SetIdObr/text()"/>
    <OBR_ObservationRequest>
      <xsl:copy-of select="./@*" />
      <xsl:copy-of select="./*" />
    </OBR_ObservationRequest>
    <xsl:for-each select="following-sibling::NTE_NotesAndComments[preceding-sibling::OBR_ObservationRequest[1]/OBR_1_SetIdObr/text()=$Anchor]">
      <NTE_NotesAndComments>
        <xsl:copy-of select="./@*" />
        <xsl:copy-of select="./*" />
      </NTE_NotesAndComments>
    </xsl:for-each>
    <xsl:for-each select="following-sibling::OBX_ObservationResult[preceding-sibling::OBR_ObservationRequest[1]/OBR_1_SetIdObr/text()=$Anchor]">
      <OBX_ObservationResult>
        <xsl:copy-of select="./@*" />
        <xsl:copy-of select="./*" />
      </OBX_ObservationResult>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

Here is the result

There is a follow up post on doing a bit more complicated mapping logic in my Mapping HL7 Data Part 2

Sorry, the comment form is closed at this time.