(newbie) EXTRACTING COMMA-SEPARATED VALUES IN XSL

alsvartr
alsvartr used Ask the Experts™
on

Hi all!

I have the following XML which has to be tranformed into JAVA via an XSL transformer:

<exceptions>
    <code_exceptions code="9,6,7"/>
    <message_code>wrongnumber</message_code>
</exceptions>

And the output must be:

case 9:
case 6:
case 7: throw new Exception(wrongnumber);
    break;

I can get it to work for two comma-separated values with XSL funcions substring -after and substring-before, but not for three values. I was thinking of a recursive solution, but I undestand recursiveness is not possible in XSL. I am required to do this in XSL, otherwise I would have used Perl.

I hope anyone can help me out with this.

Cheers!

S. Ramos
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®

Commented:
If your XSL processor allows embedded script it might have a Perl binding and then you can write all sorts of things in Perl.

Recursivitity is allowed. You define a NAMED template (it has NO match attribute) which you call with the input string as a parameter. After processing the "before comma" case, you call the named template if it contains another comma otherwise you process the after case.

I have to go for lunch now, so I'll leave you with that advice. Back either later or Monday.

HTH
Zlatin ZlatevSenior Technical Architect, Salesforce Commerce Cloud

Commented:
< snip > I undestand recursiveness is not possible in XSL < snip >

@alsvartr, This is not true - you can utilize xsl:call-template tag to achieve recursive behaviour.  As I see BigRat has suggested you to use embeded script. It is generally bad idea, because you loose the cross-platform advantage that pure XML/XSL gives you.

As BigRat sai use named template - this is what you can call using xsl:call-template.

For example see: http://xml.web.cern.ch/XML/www.dpawson.co.uk/xsl/sect2/recursion.html
Commented:
Try this
---------------------------------------
...
    <xsl:call-template name="exceptionscode">
        <xsl:param name="string" select="/exceptions/code_exceptions code" />
    </xsl:call-template>
...
</xsl:template>

<xsl:template name="exceptionscode">
    <xsl:param name="string"/>
    <xsl:param name="separator" select = ";"/>
    <xsl:choose>
        <xsl:when test="contains($string,$separator)">
            <xsl:variable name="current" select="substring-before($string, $separator)" />
            <xsl:variable name="remaining" select = "substring-after($string, $separator)"/>
            <xsl:text>case <xsl:value-of select="$current" />:
</xsl:text>
            <xsl:call-template name="exceptionscode">
                <xsl:param name="string" select="$remaining" />
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise><xsl:text>case <xsl:value-of select="$string" />: throw new Exception(wrongnumber);
   break;</xsl:text></xsl:otherwise>
    </xsl:choose>
</xsl:template>

---------------------------------------
The template recursively calls itself till no more separator is found in the string.
PMI ACP® Project Management

Prepare for the PMI Agile Certified Practitioner (PMI-ACP)® exam, which formally recognizes your knowledge of agile principles and your skill with agile techniques.

Author

Commented:
Comment to NODE:

Node, what version of XML is your solution for? I'm using XSLerator 2.5.7, and I get an error message "keyword xsl:call-template may not contain xsl:param". I tried using <xsl:with-param> tag instead of <xsl:param> and will not work. What could be the cause?

Commented:
Yes, sorry, it was a copy and paste mistake, you should use <xsl:with-param> instead of <xsl:param> at BOTH places, I mean in the first call to the template, but also in the template itself, when it calls itself. If it doesn't work, let me know what error you get, because the <xsl:with-param> is allowed in <xsl:call-template> according to w3c recomandations, I don't know if xselerator support it.

Author

Commented:
Comment for NODE:

I'm getting an error message: "Expression expected - ->,<-".

**This is how I'm calling the template:

<xsl:for-each select = "excepcion_sp[string-length(@codigo)>0]">
  <xsl:call-template name="exceptionscode">
    <xsl:with-param name="string" select="@codigo"/>
    <xsl:with-param name="message" select="mensaje"/>
  </xsl:call-template>
</xsl:for-each>

**This is the actual template:

<xsl:template name="exceptionscode">
  <xsl:param name="separator" select=","/>
  <xsl:param name="string"/>
  <xsl:param name="message"/>
  <xsl:choose>
    <xsl:when test="contains($string,$separator)">
      <xsl:variable name="current" select="substring-before($string, $separator)" />
      <xsl:variable name="remaining" select = "substring-after($string, $separator)"/>
      <xsl:text>case&#x20;<xsl:value-of select="$current" />:&#x20;</xsl:text>
      <xsl:call-template name="exceptionscode">
        <xsl:with-param name="string" select="$remaining" />
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      <xsl:text>case&#x20;<xsl:value-of select="$string" />:&#x20;throw&#x20;new&#x20;RemoteException(_msgKernel.getMessage(<xsl:text>"</xsl:text><xsl:value-of select = "$message"/><xsl:text>"</xsl:text>,&#x20;lang));<xsl:text>&#xA;break;</xsl:text></xsl:text>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

**And this is a snippet from my XML

<excepvalida variable = "_cStmt.getInt(15)">
  <excepcion_sp codigo = "4">
  <mensaje>com.ixe.isis.mw.autotransfer.outoforder</mensaje>
  </excepcion_sp>
  <excepcion_sp codigo = "5, 6, 7">
  <mensaje>com.ixe.isis.mw.autotransfer.invalidtransferdate</mensaje>
  </excepcion_sp>
</excepvalida>

Commented:
I guess it comes from
<xsl:param name="separator" select=","/>
Try
<xsl:param name="separator" select="','"/>
That should work, or at least the error should change.

Good luck !

Author

Commented:
MANY THANKS TO NODE FOR A GOOD JOB!

This solution works like this:
- When calling a named template, parameters should be enclosed within a with-param tag.
- Template parameters are announced using the param tag
- If the template does not work, try removing the text tags, for some processors will not accept value-of tags inside these.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial