Remplacer la chaîne XSLT

Je ne connais pas vraiment XSL mais je dois corriger ce code, je l'ai réduit pour le rendre plus simple.

Je reçois cette erreur

fonction XSLT/XPath invalide

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 avec?

75
demandé sur Abel 2010-06-18 07:54:16

5 réponses

replace n'est pas disponible pour XSLT 1.0.

Codesling a un modèle pour chaîne de caractères-remplacer vous pouvez utiliser comme un 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 devez littéralement remplacer un caractère par un autre, vous pouvez appeler translate qui a une signature similaire. Quelque chose comme ça devrait amende de travail:

<xsl:variable name="newtext" select="translate($text,'a','b')"/>

aussi, notez, dans cet exemple, que j'ai changé le nom de la variable en" newtext", les variables XSLT sont immuables, donc vous ne pouvez pas faire l'équivalent de $foo = $foo comme vous aviez dans votre code original.

127
répondu Mark Elliot 2016-01-08 21:16:42

Voici la fonction XSLT qui fonctionnera de la même manière que la chaîne.Remplacer () la fonction de C#.

Ce modèle a les 3 paramètres ci-dessous

texte :- votre chaîne principale

remplacer : - la chaîne que vous voulez remplacer

par : - la chaîne qui répondra par nouvelle chaîne

Ci-dessous sont les modèles

<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>

ci-dessous l'échantillon 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 le ci-dessous URL pour les détails.

33
répondu Optimus 2012-06-22 14:00:47

Note: si vous souhaitez utiliser l'algo déjà mentionné pour les cas où vous avez besoin de remplacer un grand nombre d'instances dans la chaîne source (par exemple, nouvelles lignes dans le texte long) il ya haut probabilité que vous finirez avec StackOverflowException en raison de l'appel récursif.

j'ai résolu ce problème grâce à Xalan 's (n'a pas regardé comment le faire dans Saxon ) type java intégré intégration:

<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>
11
répondu Milan Aleksić 2012-09-11 07:37:32

vous pouvez utiliser le code suivant lorsque votre processeur tourne sur .NET ou utilise MSXML (par opposition aux processeurs Java ou autres). Il utilise msxsl:script .

assurez-vous d'ajouter l'espace de nom xmlns:msxsl="urn:schemas-microsoft-com:xslt" à votre élément racine xsl:stylesheet ou xsl:transform .

en outre, liez outlet à n'importe quel espace de noms que vous aimez, par exemple xmlns: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')" />
5
répondu John Jin 2015-09-24 23:53:00

le rouine est assez bon, cependant il provoque mon application pour accrocher, donc 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 soit appelée récursivement.

j'ai eu la réponse d'ici: lors d'un essai de suspension dans une boucle infinie

Merci!

0
répondu Chesare 2017-05-23 10:31:24