Je ne connais pas vraiment XSL mais j'ai besoin de corriger ce code, je l'ai réduit pour le rendre plus simple.
Je reçois cette erreur
Fonction XSLT / XPath non valide
sur cette ligne
<xsl:variable name="text" select="replace($text,'a','b')"/>
C'est le XSL
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:inm="http://www.inmagic.com/webpublisher/query" version="1.0">
<xsl:output method="text" encoding="UTF-8" />
<xsl:preserve-space elements="*" />
<xsl:template match="text()" />
<xsl:template match="mos">
<xsl:apply-templates />
<xsl:for-each select="mosObj">
'Notes or subject'
<xsl:call-template
name="rem-html">
<xsl:with-param name="text" select="SBS_ABSTRACT" />
</xsl:call-template>
</xsl:for-each>
</xsl:template>
<xsl:template name="rem-html">
<xsl:param name="text" />
<xsl:variable name="text" select="replace($text, 'a', 'b')" />
</xsl:template>
</xsl:stylesheet>
Quelqu'un peut-il me dire ce qui ne va pas?
replace()
fonction est disponible à partir de XPath 2.0 (et donc XSLT 2.0) et prend en charge les remplacements d'expressions régulières.Réponses:
replace
n'est pas disponible pour XSLT 1.0.Le codage a un modèle de remplacement de chaîne que vous pouvez utiliser comme substitut à la fonction:
<xsl:template name="string-replace-all"> <xsl:param name="text" /> <xsl:param name="replace" /> <xsl:param name="by" /> <xsl:choose> <xsl:when test="$text = '' or $replace = ''or not($replace)" > <!-- Prevent this routine from hanging --> <xsl:value-of select="$text" /> </xsl:when> <xsl:when test="contains($text, $replace)"> <xsl:value-of select="substring-before($text,$replace)" /> <xsl:value-of select="$by" /> <xsl:call-template name="string-replace-all"> <xsl:with-param name="text" select="substring-after($text,$replace)" /> <xsl:with-param name="replace" select="$replace" /> <xsl:with-param name="by" select="$by" /> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:value-of select="$text" /> </xsl:otherwise> </xsl:choose> </xsl:template>
invoqué comme:
<xsl:variable name="newtext"> <xsl:call-template name="string-replace-all"> <xsl:with-param name="text" select="$text" /> <xsl:with-param name="replace" select="a" /> <xsl:with-param name="by" select="b" /> </xsl:call-template> </xsl:variable>
D'un autre côté, si vous n'avez littéralement besoin de remplacer qu'un caractère par un autre, vous pouvez appeler
translate
qui a une signature similaire. Quelque chose comme ça devrait fonctionner correctement:<xsl:variable name="newtext" select="translate($text,'a','b')"/>
Notez également que dans cet exemple, j'ai changé le nom de la variable en "newtext", dans XSLT les variables sont immuables, vous ne pouvez donc pas faire l'équivalent de ce
$foo = $foo
que vous aviez dans votre code d'origine.la source
translate
, nonreplace
. Lareplace
fonction dans XPath 2.0 traite son deuxième argument comme une expression régulière et remplace toutes les correspondances de cette expression par la chaîne de remplacement spécifiée (qui peut inclure des$n
références à des groupes de capture dans l' expression régulière ). Latranslate
fonction (dans 1.0 et 2.0) est celle qui effectue les remplacements de caractère unique pour un caractère unique.<xsl:with-param name="replace" select="'a'" />
entre guillemets autour du a?Voici la fonction XSLT qui fonctionnera de manière similaire à la fonction String.Replace () de C #.
Ce modèle a les 3 paramètres comme ci-dessous
texte : - votre chaîne principale
remplacer : - la chaîne que vous souhaitez remplacer
par : - la chaîne qui répondra par une nouvelle chaîne
Voici le modèle
<xsl:template name="string-replace-all"> <xsl:param name="text" /> <xsl:param name="replace" /> <xsl:param name="by" /> <xsl:choose> <xsl:when test="contains($text, $replace)"> <xsl:value-of select="substring-before($text,$replace)" /> <xsl:value-of select="$by" /> <xsl:call-template name="string-replace-all"> <xsl:with-param name="text" select="substring-after($text,$replace)" /> <xsl:with-param name="replace" select="$replace" /> <xsl:with-param name="by" select="$by" /> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:value-of select="$text" /> </xsl:otherwise> </xsl:choose> </xsl:template>
L'exemple ci-dessous montre comment l'appeler
<xsl:variable name="myVariable "> <xsl:call-template name="string-replace-all"> <xsl:with-param name="text" select="'This is a {old} text'" /> <xsl:with-param name="replace" select="'{old}'" /> <xsl:with-param name="by" select="'New'" /> </xsl:call-template> </xsl:variable>
Vous pouvez également consulter l' URL ci - dessous pour plus de détails.
la source
Remarque: Si vous souhaitez utiliser l'algo déjà mentionné pour les cas où vous devez remplacer un grand nombre d'instances dans la chaîne source (par exemple, de nouvelles lignes dans du texte long), il y a une forte probabilité que vous vous retrouviez avec à
StackOverflowException
cause de la récursivité appel.J'ai résolu ce problème grâce à l' incorporation de type Java intégrée de Xalan ( je n'ai pas regardé comment le faire dans Saxon ):
<xsl:stylesheet version="1.0" exclude-result-prefixes="xalan str" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xalan="http://xml.apache.org/xalan" xmlns:str="xalan://java.lang.String" > ... <xsl:value-of select="str:replaceAll( str:new(text()), $search_string, $replace_string)"/> ... </xsl:stylesheet>
la source
Cannot find a script or an extension object associated with namespace 'xalan://java.lang.String'.
<msxsl:script>
bloc, qui peut appeler n'importe quelle méthode .NET, bibliothèque, etc.Vous pouvez utiliser le code suivant lorsque votre processeur s'exécute sur .NET ou utilise MSXML (par opposition à Java ou à d'autres processeurs natifs). Il utilise
msxsl:script
.Assurez-vous d'ajouter l'espace
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
de noms à votre racinexsl:stylesheet
ouxsl:transform
élément.De plus, liez
outlet
à n'importe quel espace de noms que vous aimez, par exemplexmlns:outlet = "http://my.functions"
.<msxsl:script implements-prefix="outlet" language="javascript"> function replace_str(str_text,str_replace,str_by) { return str_text.replace(str_replace,str_by); } </msxsl:script> <xsl:variable name="newtext" select="outlet:replace_str(string(@oldstring),'me','you')" />
la source
prefix outlet is not defined
ou'xsl:script' cannot be a child of the 'xsl:stylesheet' element.
si je change msxsl pour mon préfixe. Je suppose que c'est une magie XSLT spécifique à Microsoft?xsl:script
, maismsxsl:script
, et il a un espace de noms différent (j'ai mis à jour la réponse de John).Je continue à frapper cette réponse. Mais aucun d'entre eux ne répertorie la solution la plus simple pour xsltproc (et probablement la plupart des processeurs XSLT 1.0):
<xsl:stylesheet version="1.0" xmlns:str="http://exslt.org/strings" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:value-of select="str:replace(., ' ', '')"/>
la source
str:replace()
fonction. Aucun des autres processeurs XSLT 1.0 majeurs - Xalan, Saxon 6.5 et Microsoft ne le fait non plus.La rouine est assez bonne, mais cela fait que mon application se bloque, alors j'ai dû ajouter le cas:
<xsl:when test="$text = '' or $replace = ''or not($replace)" > <xsl:value-of select="$text" /> <!-- Prevent thsi routine from hanging --> </xsl:when>
avant que la fonction ne soit appelée de manière récursive.
J'ai eu la réponse d'ici: lorsque le test est suspendu dans une boucle infinie
Merci!
la source