Pergunta

Se tiver um elemento seguinte no meu arquivo XSL:

<xsl:value-of select="replace(lower-case(@name), '_([a-z0-9])', '$1')" />

Por exemplo, de 'get_polygene_lubricants' que faz 'getpolygenelubricants'.

O que eu quero fazer é substituir a primeira letra depois '_' com a variante maiúscula da letra. Eu pesquisei, ler a documentação, mas eu não era capaz de encontrada qualquer solução em XSLT para esse simples substituição.

Talvez alguém sabe se é possível em XSLT 2.0?

Foi útil?

Solução

Editado :. Por esclarecimento do cartaz original, a primeira cadeia delimitada pelos sublinhados não deve ter sua letra inicial maiúscula

Esta solução não usar recursividade e deve ser muito mais eficiente .

Aqui é a nova solução :

string-join(
            (for  $i in 1 to count(tokenize(.,'_')),
                  $s in tokenize(.,'_')[$i],
                  $fl in substring($s,1,1),
                  $tail in substring($s,2)
               return
                  if($i eq 1)
                   then $s
                   else concat(upper-case($fl), $tail)
             ),
                        ''
           )

O resultado está agora exatamente como necessário:

underLinedString

Segue-se a solução de idade .

Substituir () supõe função que você tem um substituto fixo -., Portanto, não é a melhor ferramenta para resolver este problema

Aqui é uma solução 2,0 XPath de um forro (e certamente pode ser utilizado como parte de um 2,0 transformação XSLT :)):

string-join(
            (for $s in tokenize(.,'_'),
                 $fl in substring($s,1,1),
                 $tail in substring($s,2)
               return
                 concat(upper-case($fl), $tail)
             ),
            ''
           )

Quando usamos a expressão acima em uma XSLT transformação 2.0 como este :

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xsl:template match="/">
     <xsl:sequence select=
      "string-join(
                   (for $s in tokenize(.,'_'),
                    $fl in substring($s,1,1),
                    $tail in substring($s,2)
                  return
                concat(upper-case($fl), $tail)
                   ),
                   ''
                  )

      "/>
    </xsl:template>
</xsl:stylesheet>

e aplicá-lo sobre este documento XML:

<t>under_lined_String</t>

o resultado queria é produzido :

UnderLinedString

Outras dicas

Você pode fazer isso usando um modelo, de forma recursiva que chama-se para percorrer os caracteres na cadeia. Este modelo deve ter um parâmetro de posição, a partir de 1 e aumentando para cada chamada para o modelo. Quando '_' é encontrado, transformar próxima char para maiúsculas usando traduzir (1.0) ou superior-caso (2.0)

Apesar de já respondidas, aqui está a minha solução:

<xsl:template name="camel-case">
  <xsl:param name='value'/>
  <xsl:analyze-string regex="^(.)" select="$value">
    <xsl:matching-substring><xsl:value-of select="upper-case(regex-group(1))"/></xsl:matching-substring>
    <xsl:non-matching-substring>
      <xsl:analyze-string regex="[_-](.)" select=".">
        <xsl:matching-substring><xsl:value-of select="upper-case(regex-group(1))"/></xsl:matching-substring>
        <xsl:non-matching-substring><xsl:value-of select="."/></xsl:non-matching-substring>
      </xsl:analyze-string>
    </xsl:non-matching-substring>          
  </xsl:analyze-string>
</xsl:template>

Use:

<xsl:call-template name="camel-case">
  <xsl:with-param name='value' select="."/>
</xsl:call-template>
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top