Question

Est-il possible de scinder une balise entre les limites inférieure et supérieure, c.-à-d. Par exemple, la balise "UserLicenseCode" doit être convertie en "Code de licence utilisateur". afin que les en-têtes de colonnes soient un peu plus agréables.

J'ai déjà fait quelque chose comme ça dans le passé en utilisant les expressions rationnelles de Perl, mais XSLT est un tout nouveau jeu de balle pour moi.

Tous les indicateurs pour la création d'un tel modèle seraient grandement appréciés!

Merci Krishna

Était-ce utile?

La solution

En utilisant la récursivité, il est possible de parcourir une chaîne dans XSLT pour évaluer chaque caractère. Pour ce faire, créez un nouveau modèle qui accepte un seul paramètre de chaîne. Vérifiez le premier caractère et s'il s'agit d'un caractère majuscule, écrivez un espace. Puis écris le personnage. Ensuite, appelez à nouveau le modèle avec les caractères restants dans une seule chaîne. Cela donnerait ce que vous voulez faire.

Ce serait votre pointeur. Il me faudra un peu de temps pour élaborer le modèle. :-)


Il a fallu des tests, en particulier pour obtenir l’espace à l’intérieur du tout. (J'ai mal utilisé un personnage pour ça!) Mais ce code devrait vous donner une idée ...

J'ai utilisé ce XML:

<?xml version="1.0" encoding="UTF-8"?>
<blah>UserLicenseCode</blah>

puis cette feuille de style:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
    <xsl:output method="text"/>
    <xsl:variable name="Space">*</xsl:variable>
    <xsl:template match="blah">
    <xsl:variable name="Split">
        <xsl:call-template name="Split">
            <xsl:with-param name="Value" select="."/>
            <xsl:with-param name="First" select="true()"/>
        </xsl:call-template></xsl:variable>
        <xsl:value-of select="translate($Split, '*', ' ')" />
    </xsl:template>
    <xsl:template name="Split">
        <xsl:param name="Value"/>
        <xsl:param name="First" select="false()"/>
        <xsl:if test="$Value!=''">
            <xsl:variable name="FirstChar" select="substring($Value, 1, 1)"/>
            <xsl:variable name="Rest" select="substring-after($Value, $FirstChar)"/>
                <xsl:if test="not($First)">
                    <xsl:if test="translate($FirstChar, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', '..........................')= '.'">
                        <xsl:value-of select="$Space"/>
                    </xsl:if>
                </xsl:if>
                <xsl:value-of select="$FirstChar"/>
                <xsl:call-template name="Split">
                    <xsl:with-param name="Value" select="$Rest"/>
                </xsl:call-template>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

et cela a pour résultat:

User License Code

N'oubliez pas que les espaces et autres caractères d'espace blanc ont tendance à être supprimés de XML, c'est pourquoi j'ai utilisé un '*' à la place, que j'ai traduit en espace.

Bien sûr, ce code pourrait être amélioré. C'est ce que je pourrais trouver en 10 minutes de travail. Dans d’autres langues, cela prendrait moins de lignes de code, mais dans XSLT, cela reste assez rapide, compte tenu de la quantité de lignes de code qu’il contient.

Autres conseils

Une solution XSLT + FXSL (dans XSLT 2.0, mais presque le même code fonctionnera avec XSLT 1.0 et FXSL 1.x :

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:f="http://fxsl.sf.net/"
xmlns:testmap="testmap"
exclude-result-prefixes="f testmap"
>
   <xsl:import href="../f/func-str-dvc-map.xsl"/>
   <testmap:testmap/>

   <xsl:output omit-xml-declaration="yes" indent="yes"/>

   <xsl:template match="/">
     <xsl:variable name="vTestMap" select="document('')/*/testmap:*[1]"/>

     '<xsl:value-of select="f:str-map($vTestMap, 'UserLicenseCode')"
       />'
   </xsl:template>

    <xsl:template name="mySplit" match="*[namespace-uri() = 'testmap']"
     mode="f:FXSL">
      <xsl:param name="arg1"/>

      <xsl:value-of select=
       "if(lower-case($arg1) ne $arg1)
         then concat(' ', $arg1)
         else $arg1
       "/>
    </xsl:template>
</xsl:stylesheet>

Lorsque la transformation ci-dessus est appliquée à un document XML source (non utilisé), le résultat correct attendu est généré:

'Code de licence utilisateur'

Notez :

  1. Nous utilisons la version DVC de la fonction / modèle FXSL str-map () . Il s'agit d'une fonction d'ordre supérieur (HOF) qui prend deux arguments: une autre fonction et une chaîne. str-map () applique la fonction à chaque caractère de la chaîne et renvoie la concaténation des résultats.

  2. Étant donné que la fonction minuscule () est utilisée (dans la version XSLT 2.0), nous ne sommes pas limités à l'alphabet latin.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top