XSLT 2.0, заменить функцию: Как заменить соответствующую группу заглавными буквами? - PullRequest
2 голосов
/ 28 января 2009

Если в моем XSL-файле есть следующий элемент:

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

Например, из «get_polygene_lubricants» он делает «getpolygenelubricants».

Что я хочу сделать, это заменить первую букву после '_' на заглавный вариант письма. Я погуглил, прочитал документацию, но я не смог найти никакого решения в XSLT для этого простого замена.

Может, кто-нибудь знает, возможно ли это в XSLT 2.0?

Ответы [ 3 ]

6 голосов
/ 29 января 2009

Отредактировано : В соответствии с пояснениями к исходному постеру, первая строка, разделенная подчеркиванием, не должна начинаться с заглавной буквы.

Это решение не использует рекурсию и должно быть более эффективным .

Вот новое решение :

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)
             ),
                        ''
           )

Результат теперь точно соответствует требуемому:

underLinedString

Ниже старое решение .

Функция replace () предполагает, что у вас есть фиксированная замена - поэтому это не лучший инструмент для решения этой проблемы.

Вот однострочное решение XPath 2.0 (и оно, безусловно, может использоваться как часть преобразования XSLT 2.0 :)):

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

Когда мы используем вышеприведенное выражение в преобразовании XSLT 2.0, как это :

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

и примените его к этому XML-документу:

<t>under_lined_String</t>

желаемый результат получен :

UnderLinedString
1 голос
/ 28 января 2009

Вы можете сделать это, используя шаблон, рекурсивно вызывая себя для перебора символов в строке. Этот шаблон должен принимать параметр позиции, начиная с 1 и увеличивается для каждого вызова шаблона. Когда '_' найдено, преобразуйте следующий символ в верхний регистр, используя translate (1.0) или верхний регистр (2.0)

0 голосов
/ 01 августа 2011

Хотя уже ответили, вот мое решение:

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

Использование:

<xsl:call-template name="camel-case">
  <xsl:with-param name='value' select="."/>
</xsl:call-template>
...