XSLT 2.0, substituir a função: como substituir grupo combinado com letras maiúsculas?
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?
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
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>