Pregunta

¿Es posible dividir una etiqueta en los límites de mayúsculas y minúsculas? por ejemplo, la etiqueta 'UserLicenseCode' debe convertirse a 'User License Code' para que los encabezados de las columnas se vean un poco más bonitos.

He hecho algo como esto en el pasado usando las expresiones regulares de Perl, pero XSLT es un juego de pelota completamente nuevo para mí.

¡Cualquier indicador para crear una plantilla de este tipo sería muy apreciado!

Gracias Krishna

¿Fue útil?

Solución

Utilizando la recursividad, es posible caminar a través de una cadena en XSLT para evaluar cada carácter. Para hacer esto, cree una nueva plantilla que acepte solo un parámetro de cadena. Verifique el primer carácter y si es un carácter en mayúscula, escriba un espacio. Luego escribe el personaje. Luego llame a la plantilla nuevamente con los caracteres restantes dentro de una sola cadena. Esto daría como resultado lo que quieres hacer.

Ese sería tu puntero. Necesitaré algo de tiempo para resolver la plantilla. :-)


Tomó algunas pruebas, especialmente para obtener el espacio dentro de todo. (¡Utilicé mal un personaje para esto!) Pero este código debería darte una idea ...

Usé este XML:

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

y luego esta hoja de estilo:

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

y obtuve esto como resultado:

User License Code

Tenga en cuenta que los espacios y otros caracteres de espacio en blanco tienden a despojarse de XML, por lo que utilicé un '*' en su lugar, que traduje a un espacio.

Por supuesto, este código podría mejorarse. Es lo que se me ocurre en 10 minutos de trabajo. En otros idiomas, tomaría menos líneas de código, pero en XSLT sigue siendo bastante rápido, considerando la cantidad de líneas de código que contiene.

Otros consejos

Una solución XSLT + FXSL (en XSLT 2.0, pero casi el mismo código funcionará con XSLT 1.0 y 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>

Cuando la transformación anterior se aplica en cualquier documento XML de origen (no utilizado), se produce el resultado correcto esperado:

'Código de licencia de usuario'

Nota :

  1. Estamos utilizando la versión DVC de la función / plantilla FXSL str-map() . Esta es una función de orden superior (HOF) que toma dos argumentos: otra función y una cadena. str-map() aplica la función en cada carácter de la cadena y devuelve la concatenación de los resultados.

  2. Debido a que se utiliza la función en minúsculas () (en la versión XSLT 2.0), no estamos limitados solo al alfabeto latino.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top