user3872094
user3872094

Reputation: 3351

regex contains giving the wrong output

I've the below XML code.

 <pgs>IVA.004, 168IA.002</pgs>

And I'm trying to get the data before . and write a match using regex. Below is my XSLT.

<xsl:template match="pgs">
        <td class="pgs">
            <xsl:analyze-string select="." regex="([\w]+)\.([\w]+)">
                <xsl:matching-substring>
                    <xsl:variable name="nonStringFirstNum" select="number(translate(regex-group(1),'ABCDEFGHIJKLMNOPQRSTUVWXYZ',''))"/>
                    <xsl:variable name="nonStringSecondNum" select="number(translate(regex-group(3),'ABCDEFGHIJKLMNOPQRSTUVWXYZ',''))"/>
                    <xsl:variable name="refVar">
                        <xsl:choose>
                            <xsl:when test="matches(regex-group(1),'XV') or matches(regex-group(1),'Sch') or ($nonStringFirstNum > 367)">
                                <xsl:value-of select="concat('er:#Link_PT_15/P',regex-group(1),'-',regex-group(2))"/>
                            </xsl:when>
                            <xsl:when test="matches(regex-group(1),'XIII') or ($nonStringFirstNum > 348 and $nonStringFirstNum &lt; 361)">
                                <xsl:value-of select="concat('er:#Link_PT_13/P',regex-group(1),'-',regex-group(2))"/>
                            </xsl:when>
                            <xsl:when test="matches(regex-group(1),'XII') or ($nonStringFirstNum > 341 and $nonStringFirstNum &lt; 344)">
                                <xsl:value-of select="concat('er:#Link_PT_12/P',regex-group(1),'-',regex-group(2))"/>
                            </xsl:when>
                            <xsl:when test="matches(regex-group(1),'X') or ($nonStringFirstNum > 325 and $nonStringFirstNum &lt; 332)">
                                <xsl:value-of select="concat('er:#Link_PT_10/P',regex-group(1),'-',regex-group(2))"/>
                            </xsl:when>
                            <xsl:when test="matches(regex-group(1),'IX') or ($nonStringFirstNum > 323 and $nonStringFirstNum &lt; 326)">
                                <xsl:value-of select="concat('er:#Link_PT_09/P',regex-group(1),'-',regex-group(2))"/>
                            </xsl:when>
                            <xsl:when test="matches(regex-group(1),'VIII') or ($nonStringFirstNum > 306 and $nonStringFirstNum &lt; 310)">
                                <xsl:value-of select="concat('er:#Link_PT_08/P',regex-group(1),'-',regex-group(2))"/>
                            </xsl:when>
                            <xsl:when test="matches(regex-group(1),'VII') or ($nonStringFirstNum > 305 and $nonStringFirstNum &lt; 307)">
                                <xsl:value-of select="concat('er:#Link_PT_07/P',regex-group(1),'-',regex-group(2))"/>
                            </xsl:when>
                            <xsl:when test="matches(regex-group(1),'VI') or ($nonStringFirstNum > 296 and $nonStringFirstNum &lt; 303)">
                                <xsl:value-of select="concat('er:#Link_PT_06/P',regex-group(1),'-',regex-group(2))"/>
                            </xsl:when>
                            <xsl:when test="matches(regex-group(1),'V') or ($nonStringFirstNum > 168 and $nonStringFirstNum &lt; 297)">
                                <xsl:value-of select="concat('er:#Link_PT_05/P',regex-group(1),'-',regex-group(2))"/>
                            </xsl:when>
                            <xsl:when test="matches(regex-group(1),'IV') or ($nonStringFirstNum > 114 and $nonStringFirstNum &lt; 169)">
                                <xsl:value-of select="concat('er:#Link_PT_04/P',regex-group(1),'-',regex-group(2))"/>
                            </xsl:when>
                            <xsl:when test="matches(regex-group(1),'II') or ($nonStringFirstNum > 36 and $nonStringFirstNum &lt; 80)">
                                <xsl:value-of select="concat('er:#Link_PT_02/P',regex-group(1),'-',regex-group(2))"/>
                            </xsl:when>
                            <xsl:when test="matches(regex-group(1),'LT') or ($nonStringFirstNum >= 0 and $nonStringFirstNum &lt; 3)">
                                <xsl:value-of select="concat('er:#Link_PT_01/P',regex-group(1),'-',regex-group(2))"/>
                            </xsl:when>
                            <xsl:otherwise>
                                <xsl:value-of select="concat('er:#Link_CH_02/P',regex-group(1),'-',regex-group(2))"/>
                            </xsl:otherwise>
                        </xsl:choose>
                    </xsl:variable>
                    <a href="{$refVar}">
                        <xsl:value-of select="."/>
                    </a>
                </xsl:matching-substring>
                <xsl:non-matching-substring>
                    <xsl:value-of select="."/>
                </xsl:non-matching-substring>
            </xsl:analyze-string>
        </td>
    </xsl:template>

When I run this IVA.004 is giving me the output as <a href="er:#Link_PT_05/PIVA-004">IVA.004</a> instead of <a href="er:#Link_PT_04/PIVA-004">IVA.004</a>. please let me know where am I going wrong and how can I fix this. Here is a working fiddle.

http://xsltransform.net/jz1PuNJ

Thanks

Upvotes: 1

Views: 46

Answers (2)

Rudramuni TP
Rudramuni TP

Reputation: 1278

In xsl:choose, first possible xsl:when condition only return first. i.e., 'matches(regex-group(1),'V')' will return first, as expression contains 'V', I mean 'IVA.004' contains 'V', there is no chance to check the next xsl:when, because after successful condition, control will exit from further checking.

Change the order xsl:when as given below.

<xsl:when test="matches(regex-group(1),'IV') or ($nonStringFirstNum > 114 and $nonStringFirstNum &lt; 169)">
    <xsl:value-of select="concat('er:#Link_PT_04/P',regex-group(1),'-',regex-group(2))"/>
</xsl:when><!--Keep this xsl:when first-->
<xsl:when test="matches(regex-group(1),'V') or ($nonStringFirstNum > 168 and $nonStringFirstNum &lt; 297)">
    <xsl:value-of select="concat('er:#Link_PT_05/P',regex-group(1),'-',regex-group(2))"/>
</xsl:when><!--Keep this xsl:when next-->

Few more xsl:when order also needs to change as below

<xsl:when test="matches(regex-group(1),'IX') or ($nonStringFirstNum > 323 and $nonStringFirstNum &lt; 326)">
    <xsl:value-of select="concat('er:#Link_PT_09/P',regex-group(1),'-',regex-group(2))"/>
</xsl:when>
<xsl:when test="matches(regex-group(1),'X') or ($nonStringFirstNum > 325 and $nonStringFirstNum &lt; 332)">
    <xsl:value-of select="concat('er:#Link_PT_10/P',regex-group(1),'-',regex-group(2))"/>
</xsl:when>

Upvotes: 1

Martin Honnen
Martin Honnen

Reputation: 167571

The string IVA.004 matches both 'V' and 'IV' and in an xsl:choose/xsl:when the first true xsl:when is used so you would need to change the order of the xsl:choose.

Upvotes: 1

Related Questions