Search code examples
xsltxslt-2.0hl7-v2

XSL - How can I properly concatenate node values into one formatted node value


I'm trying to concatenate multiple OBX.3, OBX.5, and OBX.6 values to the end of a specific OBX.5 field. What I have written works, but not in the way that I want it to.

For example, I want this source:

OBX|1|TX|2080^Diagnosis||Sinus rhythm~Right axis deviation~Right atrial enlargement~Possible Ventricular preexcitation~Biventricular hypertrophy~~When compared with ECG of 17-JAN-2020 13:15, there is no significant change.~~~Confirmed by DOCTOR MD, DOCTOR (174) on 1/26/2020 10:57:01 PM||||||F 
OBX|2|ST|552^Ventricular Rate||126|BPM|||||F 
OBX|3|ST|554^P-R Interval||88|ms|||||F
OBX|4|ST|555^QRS Duration||90|ms|||||F 
OBX|5|ST|556^Q-T Interval||380|ms|||||F 
OBX|6|ST|557^QTC Calculation(Bazett)||550|ms|||||F

or xml version:

                        <ORU_R01.OBSERVATION>
                            <OBX>
                                <OBX.1>1</OBX.1>
                                <OBX.2>TX</OBX.2>
                                <OBX.3>
                                    <CWE.1>2080</CWE.1>
                                    <CWE.2>Diagnosis</CWE.2>
                                </OBX.3>
                                <OBX.5>Sinus rhythm</OBX.5>
                                <OBX.5>Right axis deviation</OBX.5>
                                <OBX.5>Right atrial enlargement</OBX.5>
                                <OBX.5>Possible Ventricular preexcitation</OBX.5>
                                <OBX.5>Biventricular hypertrophy</OBX.5>
                                <OBX.5>When compared with ECG of 17-JAN-2020 13:15, there is no significant change.</OBX.5>
                                <OBX.5>Confirmed by DOCTOR MD, DOCTOR (174) on 1/26/2020 10:57:01 PM</OBX.5>
                                <OBX.11>F</OBX.11>
                            </OBX>
                        </ORU_R01.OBSERVATION>
                        <ORU_R01.OBSERVATION>
                            <OBX>
                                <OBX.1>2</OBX.1>
                                <OBX.2>ST</OBX.2>
                                <OBX.3>
                                    <CWE.1>552</CWE.1>
                                    <CWE.2>Ventricular Rate</CWE.2>
                                </OBX.3>
                                <OBX.5>126</OBX.5>
                                <OBX.6>
                                    <CWE.1>BPM</CWE.1>
                                </OBX.6>
                                <OBX.11>F</OBX.11>
                            </OBX>
                        </ORU_R01.OBSERVATION>
                        <ORU_R01.OBSERVATION>
                            <OBX>
                                <OBX.1>3</OBX.1>
                                <OBX.2>ST</OBX.2>
                                <OBX.3>
                                    <CWE.1>554</CWE.1>
                                    <CWE.2>P-R Interval</CWE.2>
                                </OBX.3>
                                <OBX.5>88</OBX.5>
                                <OBX.6>
                                    <CWE.1>ms</CWE.1>
                                </OBX.6>
                                <OBX.11>F</OBX.11>
                            </OBX>
                        </ORU_R01.OBSERVATION>
                        <ORU_R01.OBSERVATION>
                            <OBX>
                                <OBX.1>4</OBX.1>
                                <OBX.2>ST</OBX.2>
                                <OBX.3>
                                    <CWE.1>555</CWE.1>
                                    <CWE.2>QRS Duration</CWE.2>
                                </OBX.3>
                                <OBX.5>90</OBX.5>
                                <OBX.6>
                                    <CWE.1>ms</CWE.1>
                                </OBX.6>
                                <OBX.11>F</OBX.11>
                            </OBX>
                        </ORU_R01.OBSERVATION>
                        <ORU_R01.OBSERVATION>
                            <OBX>
                                <OBX.1>5</OBX.1>
                                <OBX.2>ST</OBX.2>
                                <OBX.3>
                                    <CWE.1>556</CWE.1>
                                    <CWE.2>Q-T Interval</CWE.2>
                                </OBX.3>
                                <OBX.5>380</OBX.5>
                                <OBX.6>
                                    <CWE.1>ms</CWE.1>
                                </OBX.6>
                                <OBX.11>F</OBX.11>
                            </OBX>
                        </ORU_R01.OBSERVATION>
                        <ORU_R01.OBSERVATION>
                            <OBX>
                                <OBX.1>6</OBX.1>
                                <OBX.2>ST</OBX.2>
                                <OBX.3>
                                    <CWE.1>557</CWE.1>
                                    <CWE.2>QTC Calculation(Bazett)</CWE.2>
                                </OBX.3>
                                <OBX.5>550</OBX.5>
                                <OBX.6>
                                    <CWE.1>ms</CWE.1>
                                </OBX.6>
                                <OBX.11>F</OBX.11>
                            </OBX>
                        </ORU_R01.OBSERVATION>
                        <ORU_R01.OBSERVATION>
                            <OBX>
                                <OBX.1>7</OBX.1>
                                <OBX.2>RP</OBX.2>
                                <OBX.3>
                                    <CWE.1>APPWebURL</CWE.1>
                                </OBX.3>
                                <OBX.5>
                                    <RP.1>http://SERVERSQL1:8989/appcripts/appweb.dll?RetrieveTestByDateTime?PatientID=123456789&amp;Date=23-01-2020&amp;Time=12%3a21%3a05%3a00&amp;TestType=ECG&amp;Site=1&amp;OutputType=PDF&amp;Ext=PDF</RP.1>
                                </OBX.5>
                                <OBX.11>F</OBX.11>
                            </OBX>
                        </ORU_R01.OBSERVATION>

To look like this:

OBX|1|TX|2082^Diagnosis||Sinus rhythm~Right axis deviation~Right atrial enlargement~Possible Ventricular preexcitation~Biventricular hypertrophy~When compared with ECG of 17-JAN-2020 13:15, there is no significant change.~Confirmed by DOCTOR MD, DOCTOR (174) on 1/26/2020 10:57:01 PM~Ventricular Rate: 126 BPM~P-R Interval: 88 ms~QRS Duration: 90 ms~Q-T Interval: 380 ms~QTC Calculation(Bazett): 550 ms

However, i can only get it to look like this:

OBX|1|TX|2082^Diagnosis||Sinus rhythm Right axis deviation Right atrial enlargement Possible Ventricular preexcitation Biventricular hypertrophy When compared with ECG of 17-JAN-2020 13:15, there is no significant change. Confirmed by DOCTOR MD, DOCTOR (174) on 1/26/2020 10:57:01 PM\R\Ventricular Rate P-R Interval QRS Duration Q-T Interval QTC Calculation(Bazett)\R\126 88 90 380 550\R\BPM ms ms ms ms

Here is my code:

    <xsl:for-each select="ORU_R01.OBSERVATION[OBX/OBX.2!='RP']">
        <ORU_R01.OBSERVATION>
        <xsl:variable name="rpt">
            <xsl:value-of select="//OBX[OBX.2='TX']/OBX.5" />
        </xsl:variable>                                                         
            <xsl:if test="OBX/OBX.2 = 'TX'">
                <OBX>
                    <OBX.1>
                        <xsl:value-of select="'1'" />
                    </OBX.1>
                    <OBX.2>
                        <xsl:value-of select="'TX'" />
                    </OBX.2>
                    <OBX.3>
                        <CWE.1>
                            <xsl:value-of select="'2082'" />
                        </CWE.1>
                        <CWE.2>
                            <xsl:value-of select="'Diagnosis'" />
                        </CWE.2>
                    </OBX.3>
                    <OBX.5>
                        <xsl:value-of select="$rpt" />
                    </OBX.5>
                    <OBX.5>
                        <xsl:value-of select="//OBX[OBX.2='ST']/OBX.3/CWE.2" />
                    </OBX.5>
                    <OBX.5>
                        <xsl:value-of select="//OBX[OBX.2='ST']/OBX.5" />
                    </OBX.5>
                    <OBX.5>
                        <xsl:value-of select="//OBX[OBX.2='ST']/OBX.6/CWE.1" />
                    </OBX.5>                                                                        
                </OBX>
            </xsl:if>
        </ORU_R01.OBSERVATION>
    </xsl:for-each>

What do I need to do?


Solution

  • This stylesheet

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
      <xsl:strip-space elements="*"/>
      <xsl:template match="*[ORU_R01.OBSERVATION]">
            <ORU_R01.OBSERVATION>
                <OBX>
                    <OBX.1>1</OBX.1>
                    <OBX.2>TX</OBX.2>
                    <OBX.3>
                        <CWE.1>2082</CWE.1>
                        <CWE.2>Diagnosis</CWE.2>
                    </OBX.3>
                    <xsl:copy-of 
                        select="ORU_R01.OBSERVATION/OBX[OBX.2='TX']/OBX.5"/>
                    <xsl:for-each select="ORU_R01.OBSERVATION/OBX[OBX.2='ST']">
                        <OBX.5>
                            <xsl:value-of select="concat(OBX.3/CWE.2,':'),OBX.5,OBX.6/CWE.1"/>
                        </OBX.5>
                    </xsl:for-each>
                </OBX>
            </ORU_R01.OBSERVATION>
      </xsl:template>
    </xsl:stylesheet>
    

    Whit this input:

    <root> 
      <ORU_R01.OBSERVATION> 
        <OBX> 
          <OBX.1>1</OBX.1>  
          <OBX.2>TX</OBX.2>  
          <OBX.3> 
            <CWE.1>2080</CWE.1>  
            <CWE.2>Diagnosis</CWE.2> 
          </OBX.3>  
          <OBX.5>Sinus rhythm</OBX.5>  
          <OBX.5>Right axis deviation</OBX.5>  
          <OBX.5>Right atrial enlargement</OBX.5>  
          <OBX.5>Possible Ventricular preexcitation</OBX.5>  
          <OBX.5>Biventricular hypertrophy</OBX.5>  
          <OBX.5>When compared with ECG of 17-JAN-2020 13:15, there is no significant change.</OBX.5>  
          <OBX.5>Confirmed by DOCTOR MD, DOCTOR (174) on 1/26/2020 10:57:01 PM</OBX.5>  
          <OBX.11>F</OBX.11> 
        </OBX> 
      </ORU_R01.OBSERVATION>  
      <ORU_R01.OBSERVATION> 
        <OBX> 
          <OBX.1>2</OBX.1>  
          <OBX.2>ST</OBX.2>  
          <OBX.3> 
            <CWE.1>552</CWE.1>  
            <CWE.2>Ventricular Rate</CWE.2> 
          </OBX.3>  
          <OBX.5>126</OBX.5>  
          <OBX.6> 
            <CWE.1>BPM</CWE.1> 
          </OBX.6>  
          <OBX.11>F</OBX.11> 
        </OBX> 
      </ORU_R01.OBSERVATION>  
      <ORU_R01.OBSERVATION> 
        <OBX> 
          <OBX.1>3</OBX.1>  
          <OBX.2>ST</OBX.2>  
          <OBX.3> 
            <CWE.1>554</CWE.1>  
            <CWE.2>P-R Interval</CWE.2> 
          </OBX.3>  
          <OBX.5>88</OBX.5>  
          <OBX.6> 
            <CWE.1>ms</CWE.1> 
          </OBX.6>  
          <OBX.11>F</OBX.11> 
        </OBX> 
      </ORU_R01.OBSERVATION>  
      <ORU_R01.OBSERVATION> 
        <OBX> 
          <OBX.1>4</OBX.1>  
          <OBX.2>ST</OBX.2>  
          <OBX.3> 
            <CWE.1>555</CWE.1>  
            <CWE.2>QRS Duration</CWE.2> 
          </OBX.3>  
          <OBX.5>90</OBX.5>  
          <OBX.6> 
            <CWE.1>ms</CWE.1> 
          </OBX.6>  
          <OBX.11>F</OBX.11> 
        </OBX> 
      </ORU_R01.OBSERVATION>  
      <ORU_R01.OBSERVATION> 
        <OBX> 
          <OBX.1>5</OBX.1>  
          <OBX.2>ST</OBX.2>  
          <OBX.3> 
            <CWE.1>556</CWE.1>  
            <CWE.2>Q-T Interval</CWE.2> 
          </OBX.3>  
          <OBX.5>380</OBX.5>  
          <OBX.6> 
            <CWE.1>ms</CWE.1> 
          </OBX.6>  
          <OBX.11>F</OBX.11> 
        </OBX> 
      </ORU_R01.OBSERVATION>  
      <ORU_R01.OBSERVATION> 
        <OBX> 
          <OBX.1>6</OBX.1>  
          <OBX.2>ST</OBX.2>  
          <OBX.3> 
            <CWE.1>557</CWE.1>  
            <CWE.2>QTC Calculation(Bazett)</CWE.2> 
          </OBX.3>  
          <OBX.5>550</OBX.5>  
          <OBX.6> 
            <CWE.1>ms</CWE.1> 
          </OBX.6>  
          <OBX.11>F</OBX.11> 
        </OBX> 
      </ORU_R01.OBSERVATION>  
      <ORU_R01.OBSERVATION> 
        <OBX> 
          <OBX.1>7</OBX.1>  
          <OBX.2>RP</OBX.2>  
          <OBX.3> 
            <CWE.1>APPWebURL</CWE.1> 
          </OBX.3>  
          <OBX.5> 
            <RP.1>http://SERVERSQL1:8989/appcripts/appweb.dll?RetrieveTestByDateTime?PatientID=123456789&amp;Date=23-01-2020&amp;Time=12%3a21%3a05%3a00&amp;TestType=ECG&amp;Site=1&amp;OutputType=PDF&amp;Ext=PDF</RP.1> 
          </OBX.5>  
          <OBX.11>F</OBX.11> 
        </OBX> 
      </ORU_R01.OBSERVATION> 
    </root>
    

    Output:

    <ORU_R01.OBSERVATION>
       <OBX>
          <OBX.1>1</OBX.1>
          <OBX.2>TX</OBX.2>
          <OBX.3>
             <CWE.1>2082</CWE.1>
             <CWE.2>Diagnosis</CWE.2>
          </OBX.3>
          <OBX.5>Sinus rhythm</OBX.5>
          <OBX.5>Right axis deviation</OBX.5>
          <OBX.5>Right atrial enlargement</OBX.5>
          <OBX.5>Possible Ventricular preexcitation</OBX.5>
          <OBX.5>Biventricular hypertrophy</OBX.5>
          <OBX.5>When compared with ECG of 17-JAN-2020 13:15, there is no significant change.</OBX.5>
          <OBX.5>Confirmed by DOCTOR MD, DOCTOR (174) on 1/26/2020 10:57:01 PM</OBX.5>
          <OBX.5>Ventricular Rate: 126 BPM</OBX.5>
          <OBX.5>P-R Interval: 88 ms</OBX.5>
          <OBX.5>QRS Duration: 90 ms</OBX.5>
          <OBX.5>Q-T Interval: 380 ms</OBX.5>
          <OBX.5>QTC Calculation(Bazett): 550 ms</OBX.5>
       </OBX>
    </ORU_R01.OBSERVATION>
    

    Test in here

    Do note: you can copy elements as well as use a literal result element; there is no need for the xsl:value-of instruction when outputting literal text nodes; xsl:value-of semantic have change between XSLT 1.0 and XSLT 2.0 and now it can also output sequence.