7 votes

Remplacement de type "expression régulière" dans XSLT 1.0

J'ai besoin d'effectuer une recherche et un remplacement en utilisant XSLT 1.0 qui est vraiment adapté aux expressions régulières. Malheureusement, celles-ci ne sont pas disponibles dans la version 1.0 et je ne peux pas non plus utiliser les bibliothèques d'extension telles que EXSLT en raison de paramètres de sécurité que je ne peux pas modifier.

La chaîne de caractères avec laquelle je travaille ressemble à ceci :

19;#John Smith;#17;#Ben Reynolds;#1;#Terry Jackson

Je dois remplacer les numéros et ; # les caractères avec un , . Par exemple, le texte ci-dessus deviendrait :

John Smith, Ben Reynolds, Terry Jackson

Je sais qu'une fonction récursive de chaîne est nécessaire, probablement en utilisant substring et translate, mais je ne sais pas trop par où commencer.

Quelqu'un a-t-il des conseils à donner pour résoudre ce problème ? Voici ce que j'ai commencé à faire :

<xsl:template name="TrimMulti">
    <xsl:param name="FullString" />
    <xsl:variable name="NormalizedString">
        <xsl:value-of select="normalize-space($FullString)" />
    </xsl:variable>
    <xsl:variable name="Hash">#</xsl:variable>
    <xsl:choose>
        <xsl:when test="contains($NormalizedString, $Hash)">
            <!-- Do something and call TrimMulti -->
        </xsl:when>
    </xsl:choose>
</xsl:template>

10voto

Welbog Points 32952

J'espère que vous n'avez pas trop simplifié le problème pour le poser sur SO, parce que cela ne devrait pas poser de problème.

Vous pouvez définir un modèle et l'appeler de manière récursive tant que le format de la chaîne d'entrée reste cohérent.

Par exemple,

<xsl:template name="TrimMulti">
  <xsl:param name="InputString"/>
  <xsl:variable name="RemainingString" 
    select="substring-after($InputString,';#')"/>
  <xsl:choose>
    <xsl:when test="contains($RemainingString,';#')">
      <xsl:value-of 
        select="substring-before($RemainingString,';#')"/>
      <xsl:text>, </xsl:text>
      <xsl:call-template name="TrimMulti">
        <xsl:with-param 
          name="InputString"
          select="substring-after($RemainingString,';#')"/>
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$RemainingString"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

J'ai testé ce modèle avec l'appel suivant :

<xsl:template match="/">
  <xsl:call-template name="TrimMulti">
    <xsl:with-param name="InputString">19;#John Smith;#17;#Ben Reynolds;#1;#Terry Jackson</xsl:with-param>
  </xsl:call-template>
</xsl:template>

Et j'ai obtenu le résultat suivant :

John Smith, Ben Reynolds, Terry Jackson

Ce qui semble être votre objectif.

L'explication de ce qu'il fait est facile à comprendre si vous êtes familier avec la programmation fonctionnelle. L'explication de ce qu'il fait est facile à comprendre si vous êtes familier avec la programmation fonctionnelle. InputString se présente toujours sous la forme [number];#[name];#[rest of string] . Chaque appel du TrimMulti le gabarit coupe le [number];# et imprime la partie [name] puis se passe l'expression restante de manière récursive.

Le cas de base est celui où InputString se présente sous la forme [number];#[name] Dans ce cas, le RemainingString ne contiendra pas de ;# . Comme nous savons qu'il s'agit de la fin de l'entrée, nous ne sortons pas de virgule cette fois-ci.

-1voto

Don Points 1

Si les caractères ';' et '#' ne sont pas valides dans l'entrée parce qu'ils sont des délimiteurs, pourquoi la fonction translate ne fonctionnerait-elle pas ? Cela pourrait être laid (vous devez spécifier tous les caractères valides dans le deuxième argument et les répéter dans le troisième argument) mais ce serait plus facile à déboguer.

translate($InputString, ';#abcdefghijklmnopqrstuvABCDEFGHIJKLMNOPQRSTUZ0123456789,- ', ', abcdefghijklmnopqrstuvABCDEFGHIJKLMNOPQRSTUZ0123456789,- ')

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X