Domanda

È possibile dividere un tag ai limiti maiuscoli e minuscoli, ad es. ad esempio, il tag "UserLicenseCode" deve essere convertito in "Codice licenza utente" in modo che le intestazioni delle colonne siano un po 'più belle.

Ho fatto qualcosa di simile in passato usando le espressioni regolari di Perl, ma XSLT è un gioco con la palla completamente nuovo per me.

Qualsiasi suggerimento nella creazione di un tale modello sarebbe molto apprezzato!

Grazie Krishna

È stato utile?

Soluzione

Utilizzando la ricorsione, è possibile scorrere una stringa in XSLT per valutare ogni carattere. Per fare ciò, creare un nuovo modello che accetta solo un parametro stringa. Controlla il primo carattere e se è un carattere maiuscolo, scrivi uno spazio. Quindi scrivi il personaggio. Quindi chiama nuovamente il modello con i caratteri rimanenti all'interno di una singola stringa. Ciò comporterebbe quello che vuoi fare.

Questo sarebbe il tuo puntatore. Avrò bisogno di un po 'di tempo per elaborare il modello. :-)


Ci sono voluti alcuni test, soprattutto per ottenere lo spazio all'interno del tutto. (Ho usato un personaggio per questo!) Ma questo codice dovrebbe darti un'idea ...

Ho usato questo XML:

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

e quindi questo foglio di stile:

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

e ho ottenuto questo come risultato:

User License Code

Tieni presente che gli spazi e gli altri caratteri degli spazi bianchi tendono a essere rimossi dall'XML, motivo per cui ho usato invece un '*', che ho tradotto in uno spazio.

Naturalmente, questo codice potrebbe essere migliorato. È quello che ho potuto inventare in 10 minuti di lavoro. In altre lingue, richiederebbe meno righe di codice ma in XSLT è ancora abbastanza veloce, considerando la quantità di righe di codice che contiene.

Altri suggerimenti

Una soluzione XSLT + FXSL (in XSLT 2.0, ma quasi lo stesso codice funzionerà con XSLT 1.0 e 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>

Quando la trasformazione di cui sopra viene applicata su qualsiasi documento XML di origine (non utilizzato), viene prodotto il risultato corretto previsto:

'Codice licenza utente'

Nota :

  1. Stiamo usando la versione DVC della funzione / modello FXSL str-map() . Questa è una funzione di ordine superiore (HOF) che accetta due argomenti: un'altra funzione e una stringa. str-map() applica la funzione su ogni carattere della stringa e restituisce la concatenazione dei risultati.

  2. Poiché viene utilizzata la funzione minuscola () (nella versione XSLT 2.0), non siamo vincolati solo all'alfabeto latino.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top