I'm working on a xsl template and one specific string is giving me a hard time.
<prixmenu>29.00-90.00</prixmenu>
Desired output :
<prixmenu>29€-90€</prixmenu>
The whole code I have is : XML (input) :
<?xml version="1.0" encoding="UTF-8"?>
<data>
<etablissement not="15.0" etoile="2" >
<nom>L'Auberge Asterix</nom>
<index>AUBERGE ASTERIX (L')</index>
<id>0123456789</id>
<regionindex>Paris</regionindex>
<equipe>
<chef>Ratatouille</chef>
</equipe>
<pictoPratique cave_remarquable="0" coeur="0" ></pictoPratique>
<coordonnees>
<adresse>Random adress</adresse>
<tel>01 23 45 67 89/tel>
<fermetures>mam,maa,</fermetures>
<pratique terrasse="0"
voiturier="0"
parcPrive="1"
handicap="0"
airConditione="0"
piscine="0"
tennis="0"
chien="1"
relaischat="0"
delivery="0"
clickAndCollect="0"
itineraireGourmand="0"
menu_kids="1"
hebergement="0"
></pratique>
</coordonnees>
<texte>Lorem ipsum</texte>
<prixrestau>
<prixcarte>0</prixcarte>
<prixmenu>29.00-90.00</prixmenu>
</prixrestau>
</etablissement>
</data>
XSL stylesheet :
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="data | node()[not(self::coordonnees)]">
<xsl:copy>
<xsl:apply-templates select="nom" />
<xsl:choose>
<xsl:when test="@etoile = 1">
<etoile>1 étoile</etoile>
</xsl:when>
<xsl:when test="@etoile > 1">
<etoile><xsl:value-of select="@etoile" /> étoiles</etoile>
</xsl:when>
</xsl:choose>
<xsl:apply-templates select="index" />
<xsl:apply-templates select="id" />
<xsl:apply-templates
select="@*[not(.='0')][name( ) != 'etoile'] | node()[not(self::index)][not(self::id)][not(self::prixrestau)][not(self::nom)][not(self::etoile)]" />
</xsl:copy>
</xsl:template>
<xsl:template match="@*[name( ) != 'etoile']">
<xsl:element name="{name()}">
<xsl:value-of select="number(.)" />
</xsl:element>
</xsl:template>
<xsl:template match="prixrestau/prixmenu" name="split">
<xsl:param name="pText" select="."/>
<xsl:if test="$pText">
<xsl:value-of select="number(substring-before(concat($pText, '-'), '-'))"/>
<xsl:call-template name="split">
<xsl:with-param name="pText" select="substring-after($pText, '-')"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template match="coordonnees">
<xsl:copy>
<xsl:apply-templates select="adresse" />
<xsl:apply-templates select="tel" />
<xsl:element name="prixrestau">
<xsl:value-of select="translate(../prixrestau/prixmenu,'.00.','€')"/>
<xsl:apply-templates select="../prixrestau/prixcarte[not(.='0')]" />
<xsl:element name="prixmenu">
<xsl:apply-templates select="../prixrestau/prixmenu" />
</xsl:element>
</xsl:element>
<xsl:apply-templates select="fermetures" />
<xsl:apply-templates
select="@*[not(.='0')] | node()[not(self::adresse)][not(self::tel)][not(self::fermetures)]" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Desired output :
<?xml version="1.0"?>
<data>
<etablissement>
<nom>L'Auberge Asterix</nom>
<etoile>2 étoiles</etoile>
<index>AUBERGE ASTERIX (L')</index>
<id>0123456789</id>
<not>13</not>
<regionindex>Paris</regionindex>
<equipe>
<chef>Ratatouille</chef>
</equipe>
<pictoPratique/>
<coordonnees>
<adresse>Random adress</adresse>
<tel>01 23 45 67 89</tel>
<prixrestau><prixmenu>29€-90€</prixmenu></prixrestau>
<fermetures>mam,maa,</fermetures>
<pratique>
<parcPrive>1</parcPrive>
<chien>1</chien>
<menu_kids>1</menu_kids>
</pratique>
</coordonnees>
<texte>Lorem ipsum</texte>
</etablissement>
</data>
Any suggestions on how to proceed ? Should I import FXSL or switch to XSLT 2.0 as it probably be less of a pain to get to the desired result ?
I've tried splitting it with the following code (I belive it's called a 'recursive template" :
<xsl:template match="prixrestau/prixmenu" name="split">
<xsl:param name="pText" select="."/>
<xsl:if test="$pText">
<xsl:value-of select="number(substring-before(concat($pText, '-'), '-'))"/>
<xsl:call-template name="split">
<xsl:with-param name="pText" select="substring-after($pText, '-')"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
This outputs
<prixmenu>2990</prixmenu>
And i've also tried
<xsl:value-of select="translate(../prixrestau/prixmenu,'.00.','€')"/>
and the output is :
29€-9€
Because '.00.' and '€'don't have the same length (MDN reference)...
How about:
<xsl:template match="prixmenu">
<xsl:copy>
<xsl:value-of select="format-number(substring-before(., '-'), '0€')"/>
<xsl:text>-</xsl:text>
<xsl:value-of select="format-number(substring-after(., '-'), '0€')"/>
</xsl:copy>
</xsl:template>
If you like, you could change the first xsl:value-of
instruction to:
<xsl:value-of select="format-number(substring-before(., '-'), '0€-')"/>
and get rid of the xsl:text
part - but I think it's better to keep it to make the code more readable.