user3457336
user3457336

Reputation:

String modification in XSLT

What is the equivalent XSLT code for the Java code below?

    if (s.length() > 11) {
        return s.substring(0, 8) + s.substring(9, 12);
    }
    if (s.length() == 11) {
        return s;
    }
    return s;

I have to so same above check on a field called: Lkup_CODE:

<Identifier>
    <xsl:value-of select="Lkup_CODE" />
</Identifier>

Regards,

Chaitu

Upvotes: 1

Views: 63

Answers (2)

Anthony Accioly
Anthony Accioly

Reputation: 22471

For an imperative (and discouraged) solution try the following:

<xsl:choose>
  <xsl:when test="string-length(Lkup_CODE) &gt; 11">
    <xsl:value-of select="concat(substring($Lkup_CODE, 1, 8), substring(Lkup_CODE, 10, 3))"/>
  </xsl:when>
  <xsl:when test="string-length(Lkup_CODE) = 11">
    <xsl:value-of select="Lkup_CODE"/>
  </xsl:when>
  <xsl:otherwise>
    <xsl:value-of select="Lkup_CODE"/>
  </xsl:otherwise>
</xsl:choose>

Upvotes: 2

helderdarocha
helderdarocha

Reputation: 23627

Here is a test case. Assuming you use a source such as:

<Codes>
    <Lkup_CODE>01234567:ABCDEF</Lkup_CODE> <!-- string length > 11  -->
    <Lkup_CODE>01234567:A</Lkup_CODE>      <!-- string length < 11  -->
    <Lkup_CODE>01234567:AB</Lkup_CODE>     <!-- string length == 11 -->
</Codes>

You can deal with each case using a different template for Lkup_CODE, matching the string length of its contents. For example, this XPath expression will match a code that is exactly 11 characters long (the last one):

Lkup_CODE[string-length(.)=11]

You could use a single template for the equality case and the less-than, since they return the same result. You could have different ones in case you need to deal differently with each case:

<xsl:template match="Lkup_CODE[string-length(.)=11]">
    <Identifier>
        <xsl:value-of select="."/>
    </Identifier>
</xsl:template>

<xsl:template match="Lkup_CODE[string-length(.) &lt; 11]">
    <Identifier>
        <xsl:value-of select="."/>
    </Identifier>
</xsl:template>

For the greater-than case, you have to deal with substrings. In XPath the string starts in 1, and the substring() function includes the first position and the number of characters to extract after that instead of a position, as in Java. This would be the Java / XPath mapping for your functions:

  • Chars 1 to 8 in Java: s.substring(0, 8) == in XPath: substring(s, 1, 8)
  • Chars 10 to 12 in Java: s.substring(9, 13) == in XPath: substring(s, 10, 3)

This template will deal with that condition:

<xsl:template match="Lkup_CODE[string-length(.) &gt; 11]">
    <Identifier>
        <xsl:value-of select="concat(substring(.,1,8),substring(., 10,3))"/>
    </Identifier>
</xsl:template>

Here is a full stylesheet for the test case I included at the beginning of this answer:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

    <xsl:template match="Codes">
        <Result>
            <xsl:apply-templates/>
        </Result>
    </xsl:template>

    <xsl:template match="Lkup_CODE[string-length(.)=11]">
        <Identifier>
            <xsl:value-of select="."/>
        </Identifier>
    </xsl:template>

    <xsl:template match="Lkup_CODE[string-length(.) &lt; 11]">
        <Identifier>
            <xsl:value-of select="."/>
        </Identifier>
    </xsl:template>

    <xsl:template match="Lkup_CODE[string-length(.) &gt; 11]">
        <Identifier>
            <xsl:value-of select="concat(substring(.,1,8),substring(., 10,3))"/>
        </Identifier>
    </xsl:template>

</xsl:stylesheet>

It will produce the following result:

<Result>
    <Identifier>01234567ABC</Identifier> <!-- modified because > 11 -->
    <Identifier>01234567:A</Identifier>  <!-- unmodified because < 11 -->
    <Identifier>01234567:AB</Identifier> <!-- unmodified because = 11 -->
</Result>

Upvotes: 1

Related Questions