Can I achieve something similar to a SQL IN with an xsl:if?

Viewed 26

I have an XSL IF statement that works and I could probably achieve what I need by writing multiple XSL IF statements but wanted to ask if there is a way I can use XSL IF to do something similar to SQL IN functionality.

In my data the field sce_moac.sce.srs could be one of about 20 numeric values. I want to use XSL into transform these 20 values to one of three values held in the XML (crs_udf5.crs.srs, crs_udf6.crs.srs, crs_udf7.crs.srs).

XML

<exchange>
 <sce>
  <sce.srs>
   <sce_scjc.sce.srs>560021325/2</sce_scjc.sce.srs>
   <sce_seq2.sce.srs>06</sce_seq2.sce.srs>
   <sce_moac.sce.srs>01</sce_moac.sce.srs>
  <crs>
    <crs.srs>
     <crs_udf5.crs.srs>114</crs_udf5.crs.srs>
     <crs_udf6.crs.srs>115</crs_udf6.crs.srs>
     <crs_udf7.crs.srs>118</crs_udf7.crs.srs>
    </crs.srs>
   </crs>
  </sce.srs>
 </sce>
</exchange>

XSL

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text" media-type="text/x-json"/>
 <xsl:template match="/">  
<xsl:apply-templates />
</xsl:template>  
  
<xsl:template match="/">    
 <xsl:text>[</xsl:text> 
<xsl:for-each select="/exchange/sce/sce.srs/sce_seq2.sce.srs">
<xsl:text> {PATRONCODE":"</xsl:text>
    <xsl:if test="..//sce_moac.sce.srs=01">
      <xsl:value-of select="../../..//crs_udf5.crs.srs"/>
    </xsl:if>
<xsl:text>"</xsl:text>
<xsl:text>}</xsl:text>  
<xsl:if test="position() != last()">,</xsl:if>          
 </xsl:for-each>
 <xsl:text>]</xsl:text>   
</xsl:template>
</xsl:stylesheet>

What I would like to do is to have a list of values instead of one value in my xsl:if test so instead of <xsl:if test="..//sce_moac.sce.srs=01"> I would have something that had a boolean OR so was more like this <xsl:if test="..//sce_moac.sce.srs=01|02|43"> but this syntax isn't valid. Is there a way to do this?

1 Answers

XPath/XSLT 2.0 (and up)

You can specify a sequence of values against which to test:

<xsl:if test="..//sce_moac.sce.srs=('01','02','43')">

XPath/XSLT 1.0

You would usually break the values into separate logical OR conditions:

<xsl:if test="..//sce_moac.sce.srs='01' or 
              ..//sce_moac.sce.srs='02' or
              ..//sce_moac.sce.srs='43')">

Note that in applying the above pattern you'll likely want to capture the LHS in a variable rather than repeating the XPath.

Dimitre Novatchev also has a clever trick (+1) that you might like to apply here if you have to use XSLT 1.0.

Related