1

I am working with a CCD XML document, it contains data like this:

<tr ID="encounter17" >
    <td>09/18/2012</td>
    <td ID="type41">Office Visit</td>
    <td>Family Practice</td>
    <td>
        <paragraph>REDACTED</paragraph>
    </td>
    <td />
</tr>
<tr ID="encounter18" styleCode="altRow">
    <td>09/17/2012</td>
    <td ID="type42">Office Visit</td>
    <td>Family Practice</td>
    <td>
        <paragraph>REDACTED</paragraph>
    </td>
    <td />
</tr>

I am trying to render this as HTML using the "standard" CCD.xsl, Derived from HL7 Finland R2 Tyylitiedosto: Tyyli_R2_B3_01.xslt Updated by Calvin E. Beebe, Mayo Clinic - Rochester Mn.

The element with the ID encounter17 will render, the element with the ID encounter18 will not render. Looking at the output of xsltproc this is happening because the XSLT does not recognize the styleCode attribute. Only Bold, Italic, Underline are supported.

How can I change this XSLT so that it tolerates an unknown styleCode?

<!--    Stylecode processing
  Supports Bold, Underline and Italics display-->
<xsl:template match="//n1:*[@styleCode]">

<xsl:if test="@styleCode='Bold'">
    <xsl:element name='b'>
        <xsl:apply-templates/>
    </xsl:element>
</xsl:if>

<xsl:if test="@styleCode='Italics'">
    <xsl:element name='i'>
        <xsl:apply-templates/>
    </xsl:element>
</xsl:if>

<xsl:if test="@styleCode='Underline'">
    <xsl:element name='u'>
        <xsl:apply-templates/>
    </xsl:element>
</xsl:if>

<xsl:if test="contains(@styleCode,'Bold') and contains(@styleCode,'Italics') and not (contains(@styleCode, 'Underline'))">
    <xsl:element name='b'>
        <xsl:element name='i'>
            <xsl:apply-templates/>
        </xsl:element>
    </xsl:element>
</xsl:if>

<xsl:if test="contains(@styleCode,'Bold') and contains(@styleCode,'Underline') and not (contains(@styleCode, 'Italics'))">
    <xsl:element name='b'>
        <xsl:element name='u'>
            <xsl:apply-templates/>
        </xsl:element>
    </xsl:element>
</xsl:if>

<xsl:if test="contains(@styleCode,'Italics') and contains(@styleCode,'Underline') and not (contains(@styleCode, 'Bold'))">
    <xsl:element name='i'>
        <xsl:element name='u'>
            <xsl:apply-templates/>
        </xsl:element>
    </xsl:element>
</xsl:if>

<xsl:if test="contains(@styleCode,'Italics') and contains(@styleCode,'Underline') and contains(@styleCode, 'Bold')">
    <xsl:element name='b'>
        <xsl:element name='i'>
            <xsl:element name='u'>
                <xsl:apply-templates/>
            </xsl:element>
        </xsl:element>
    </xsl:element>
</xsl:if>

I have already tried adding:

<xsl:if test="not (contains(@styleCode,'Italics')) and not (contains(@styleCode,'Underline')) and not (contains(@styleCode, 'Bold'))">
    <xsl:apply-templates/>
</xsl:if>

This seems to just render the element, it doesn't "fall through" to the part of the XSLT that deals with the <tr> tag.

LarsH
  • 27,481
  • 8
  • 94
  • 152
Freiheit
  • 8,408
  • 6
  • 59
  • 101
  • What do you mean by 'This seems to just render the element, it doesn't "fall through" to the part of the XSLT that deals with the `` tag.'? The whole template you showed is dealing with the `` tag. What is the desired output, in contrast to the actual output? – LarsH Sep 27 '12 at 16:29
  • The desired output is for `encounter17` and `encounter18` to each be a separate row. With the original XSLT, `encounter18` is not rendered because of the unrecognized value in `styleCode`. With my attempted changes `encounter18` shows up as additional columns in the same row as `encounter17` instead of a separate row. – Freiheit Sep 27 '12 at 16:47

1 Answers1

2

What horrible code! In 2.0 you want to do it like this:

<xsl:template match="n1:*[contains(@styleCode,'Bold')]" priority="100">
  <b><xsl:next-match/></b>
</xsl:template>

<xsl:template match="n1:*[contains(@styleCode,'Italic')]" priority="99">
  <i><xsl:next-match/></i>
</xsl:template>

<xsl:template match="n1:*[contains(@styleCode,'Underline')]" priority="98">
  <u><xsl:next-match/></u>
</xsl:template>

That's essentially all. This will ignore any stylecode not in the list.

You can do the same thing in 1.0 using xsl:apply-imports, but the three rules then need to be in separate stylesheet modules.

Michael Kay
  • 156,231
  • 11
  • 92
  • 164
  • Can you show how do this in 1.0? Since I'm modifying an XSLT that is a de facto standard, and it is written in 1.0 I want to keep using 1.0 to be as compatible as possible. – Freiheit Sep 27 '12 at 17:23
  • 1
    Put each of the template rules shown into a different module; change the xsl:next-match to xsl:apply-imports; and arrange it so that each module imports the one shown with next lower priority (the priority will be ignored in this scenario). – Michael Kay Sep 27 '12 at 17:40
  • Whoops, I just broke my self-imposed rule that I don't do XSLT 1.0 these days. I'll be answering COBOL questions next. – Michael Kay Sep 27 '12 at 17:41
  • Replacing "next-match" with "apply-imports" worked for me. Thanks a lot. – gbdcool Jan 21 '15 at 23:00