views:

181

answers:

1

I'm a complete XSL novice, writing an XSL file to format lots of different error messages that can appear in the output log created by an application into CSV format.

Slight variations might occur in the matchable tags in these output logs. For example, one sentence in the log might contain the phrase "Service Month/Year:" but another one, from a different area of the application, would contain "Svc Month/Yr:" instead.

Is there a way to put both those variations of that phrase in a single line of my XSL? Or do I have to repeat the entire If block, with each variation in the phrase that I want to match on in its own If block?

I tried posting the XSL here surrounded by backticks, but it runs all together in one big lump that's impossible to read. If anyone can help with this question, I'm happy to post it if you tell me how to make it readable. :-)

Thank you.

+3  A: 

XSL allows combining of conditional statements like other langues. Each one doesn't require its on if statement. Were you thinking something along these lines?

<xsl:choose>
  <xsl:when test="contains(text(), 'Service Month/Year:')
               or contains(text(), 'Svc Month/Yr:')
               ">
    <!-- do something -->
  </xsl:when>
</xsl:choose>

Keep in mind xml/xsl is case sensitive. To make it more flexible, it is even more verbose:

<xsl:variable name="lower" select="'abcdefghijklmnopqrstuvwxyz'"/>
<xsl:variable name="upper" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
<xsl:choose>
  <xsl:when test="contains(translate(text(), $upper, $lower), 'service month/year:')
               or contains(translate(text(), $upper, $lower), 'svc month/yr:')
               ">
    <!-- do something -->
  </xsl:when>
</xsl:choose>

EDIT: And an even better answer I whipped up

<xsl:template name="containsToken">
  <xsl:param name="inputString"/>
  <xsl:param name="tokens"/>
  <xsl:param name="delimiter"/>
  <xsl:variable name="lower" select="'abcdefghijklmnopqrstuvwxyz'"/>
  <xsl:variable name="upper" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>

  <xsl:choose>
    <xsl:when test="contains($tokens, $delimiter)">
      <xsl:variable name="token">
        <xsl:value-of select="substring-before($tokens, $delimiter)"/>
      </xsl:variable>
      <xsl:choose>
        <xsl:when test="contains(translate($inputString, $upper, $lower), translate($token, $upper, $lower))">
          <xsl:text>True</xsl:text>
        </xsl:when>
        <xsl:otherwise>
          <!-- loop -->
          <xsl:call-template name="containsToken">
            <xsl:with-param name="inputString" select="$inputString"/>
            <xsl:with-param name="tokens" select="substring-after($tokens, $delimiter)"/>
            <xsl:with-param name="delimiter" select="$delimiter"/>
          </xsl:call-template>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:when>
    <xsl:otherwise>
      <xsl:choose>
        <xsl:when test="contains(translate($inputString, $upper, $lower), translate($tokens, $upper, $lower))">
          <xsl:text>True</xsl:text>
        </xsl:when>
        <xsl:otherwise>
          <xsl:text>False</xsl:text>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

Usage:

<xsl:variable name="found">
  <xsl:call-template name="containsToken">
    <xsl:with-param name="inputString" select="text()"/>
    <xsl:with-param name="tokens" select="'Service Month/Year:|Svc Month/Yr:'"/>
    <xsl:with-param name="delimiter" select="'|'"/>
  </xsl:call-template>
</xsl:variable>

<xsl:if test="$found = 'True'">
  <!-- process -->
</xsl:if>

Delimiter can be whatever character or charcters you want. Tokens is a list of things to search for with the delimiter between each one. Enjoy!

fearphage
Thank you so much, fearphage. This is very helpful.
Care to mark it as *the* answer if it resolved your issue? Thanks.
fearphage