Преобразуйте целочисленное значение в повторяющийся символ - PullRequest
6 голосов
/ 12 июля 2010

Когда мои таблицы стилей XSL встречаются с этим узлом:

<node attribute="3"/>

... он должен преобразовать его в этот узел:

<node attribute="***"/>

Мой шаблон соответствует атрибуту и ​​воссоздает его, но я не знаю, как установить значение: символ '*' повторяется столько раз, сколько значение исходного атрибута.

<xsl:template match="node/@attribute">
    <xsl:variable name="repeat" select="."/>
    <xsl:attribute name="attribute">
        <!-- What goes here? I think I can do something with $repeat... -->
    </xsl:attribute>
</xsl:template>

Спасибо!

Ответы [ 3 ]

9 голосов
/ 12 июля 2010

Универсальное рекурсивное решение (XSLT 1.0):

<xsl:template name="RepeatString">
  <xsl:param name="string" select="''" />
  <xsl:param name="times"  select="1" />

  <xsl:if test="number($times) &gt; 0">
    <xsl:value-of select="$string" />
    <xsl:call-template name="RepeatString">
      <xsl:with-param name="string" select="$string" />
      <xsl:with-param name="times"  select="$times - 1" />
    </xsl:call-template>
  </xsl:if>
</xsl:template>

Позвонить как:

<xsl:attribute name="attribute">
  <xsl:call-template name="RepeatString">
    <xsl:with-param name="string" select="'*'" />
    <xsl:with-param name="times"  select="." />
  </xsl:call-template>
</xsl:attribute>
8 голосов
/ 12 июля 2010

Довольно грязный, но прагматичный подход - позвонить на самый высокий номер, который вы когда-либо ожидали увидеть в attribute, а затем набрать

.
substring("****...", 1, $repeat)

, если в этой строке столько *, сколько максимальное ожидаемое число. Но я надеюсь, что есть что-то лучшее!

7 голосов
/ 12 июля 2010

В дополнение к двум хорошим ответам @AakashM и @Tomalak, это делается естественным образом в XSLT 2.0 :

Это преобразование 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:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="@attribute">
   <xsl:attribute name="{name()}">
     <xsl:for-each select="1 to .">
       <xsl:value-of select="'*'"/>
     </xsl:for-each>
   </xsl:attribute>
 </xsl:template>
</xsl:stylesheet>

при применении к предоставленному документу XML :

<node attribute="3"/>

дает требуемый результат :

<node attribute="***"/>

Обратите внимание , как оператор XPath 2.0 to используется в инструкции <xsl:for-each>.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...