Comment limiter le nombre de mots de chaîne dans XSLT 1.0?
Question
Comment puis-je limiter le nombre de mots d'une chaîne dans XSLT 1.0?
La solution
Que diriez-vous de quelque chose comme:
<xsl:template match="data"> <!-- your data element or whatever -->
<xsl:call-template name="firstWords">
<xsl:with-param name="value" select="."/>
<xsl:with-param name="count" select="4"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="firstWords">
<xsl:param name="value"/>
<xsl:param name="count"/>
<xsl:if test="number($count) >= 1">
<xsl:value-of select="concat(substring-before($value,' '),' ')"/>
</xsl:if>
<xsl:if test="number($count) > 1">
<xsl:variable name="remaining" select="substring-after($value,' ')"/>
<xsl:if test="string-length($remaining) > 0">
<xsl:call-template name="firstWords">
<xsl:with-param name="value" select="$remaining"/>
<xsl:with-param name="count" select="number($count)-1"/>
</xsl:call-template>
</xsl:if>
</xsl:if>
</xsl:template>
Autres conseils
Ceci est une solution XSLT 1.0 :
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common"
>
<xsl:import href="strSplit-to-Words.xsl"/>
<xsl:output indent="yes" omit-xml-declaration="yes"/>
<xsl:template match="/">
<xsl:variable name="vwordNodes">
<xsl:call-template name="str-split-to-words">
<xsl:with-param name="pStr" select="/"/>
<xsl:with-param name="pDelimiters"
select="', 	 ()-'"/>
</xsl:call-template>
</xsl:variable>
<xsl:call-template name="strTakeWords">
<xsl:with-param name="pN" select="10"/>
<xsl:with-param name="pText" select="/*"/>
<xsl:with-param name="pWords"
select="ext:node-set($vwordNodes)/*"/>
</xsl:call-template>
</xsl:template>
<xsl:template match="word" priority="10">
<xsl:value-of select="concat(position(), ' ', ., ' ')"/>
</xsl:template>
<xsl:template name="strTakeWords">
<xsl:param name="pN" select="10"/>
<xsl:param name="pText"/>
<xsl:param name="pWords"/>
<xsl:param name="pResult"/>
<xsl:choose>
<xsl:when test="not($pN > 0)">
<xsl:value-of select="$pResult"/>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="vWord" select="$pWords[1]"/>
<xsl:variable name="vprecDelims" select=
"substring-before($pText,$pWords[1])"/>
<xsl:variable name="vnewText" select=
"concat($vprecDelims, $vWord)"/>
<xsl:call-template name="strTakeWords">
<xsl:with-param name="pN" select="$pN -1"/>
<xsl:with-param name="pText" select=
"substring-after($pText, $vnewText)"/>
<xsl:with-param name="pWords" select=
"$pWords[position() > 1]"/>
<xsl:with-param name="pResult" select=
"concat($pResult, $vnewText)"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
lorsque cette transformation est appliquée sur le document XML suivant:
<t>
(CNN) -- Behind closed doors in recent days,
senior White House aides have been saying that
measuring President Obama's first 100 days
is the journalistic equivalent of a Hallmark holiday.
</t>
le résultat souhaité est renvoyé :
(CNN) - À huis clos ces derniers jours,
Maison blanche senior
Notez :
-
Le
str-diviser en mots
modèle de FXSL est utilisé pour la génération de jetons. -
Ce modèle accepte un paramètre
pDelimiters
, qui est une chaîne composée de tous les caractères devant être traités comme des délimiteurs. Ainsi, contrairement aux autres solutions, il est possible de spécifier tous les délimiteurs (et pas seulement un "espace") - dans ce cas, 8 d'entre eux. -
Le modèle nommé
strTakeWords
s’appelle de manière récursive pour accumuler le texte avant et y compris chaque mot de la liste de mots produite par la tokénisation, jusqu’au nombre de mots spécifié. a été traité.