Преобразуйте int в символ - PullRequest
       32

Преобразуйте int в символ

2 голосов
/ 26 ноября 2011

Я хотел бы написать алфавит со ссылкой на каждую букву. Поэтому я использовал шаблоны, но я не знаю, как сделать это письмо, я попробовал это, но у меня была нормальная ошибка: (десятичное представление должно сразу следовать за символом & # в ссылке на символ).

<xsl:template name="alphabet">
    <xsl:param name="iLetter"/>
    <xsl:if test="$iLetter &lt; 91">
        <a><xsl:attribute name="href">req.html?X_letter=&#<xsl:value-of select="$iLetter"/>;</xsl:attribute>&#<xsl:value-of select="$iLetter"/>;</xsl:attribute></a>
        <xsl:call-template name="alphabet">
            <xsl:with-param name="iLetter" select="number($iLetter)+1"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

И я называю этот шаблон как:

<xsl:call-template name="alphabet">
        <xsl:with-param name="iLetter" select="number(65)"/>
</xsl:call-template>

Итак, я бы хотел получить такой результат:

A B C D ..... X Y Z без ... конечно:)

Ответы [ 4 ]

1 голос
/ 26 ноября 2011

В настоящее время принят неверный ответ, потому что он не дает правильного текстового дочернего элемента любого элемента a.

Вот правильное решение XSLT 1.0 :

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:variable name="vAlpha" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>

 <xsl:template match="/">
     <xsl:call-template name="alphabet"/>
 </xsl:template>

 <xsl:template name="alphabet">
  <xsl:param name="pCode" select="65"/>
  <xsl:if test="not($pCode > 90)">
    <xsl:variable name="vChar" select=
     "substring($vAlpha, $pCode - 64, 1)"/>
    <a href="req.html?X_letter={$vChar}">
     <xsl:value-of select="$vChar"/>
    </a>
    <xsl:call-template name="alphabet">
      <xsl:with-param name="pCode" select="$pCode+1"/>
    </xsl:call-template>
   </xsl:if>
 </xsl:template>
</xsl:stylesheet>

при применении к любому XML-документу (не используется), получается нужный, правильный результат :

<a href="req.html?X_letter=A">A</a>
<a href="req.html?X_letter=B">B</a>
<a href="req.html?X_letter=C">C</a>
<a href="req.html?X_letter=D">D</a>
<a href="req.html?X_letter=E">E</a>
<a href="req.html?X_letter=F">F</a>
<a href="req.html?X_letter=G">G</a>
<a href="req.html?X_letter=H">H</a>
<a href="req.html?X_letter=I">I</a>
<a href="req.html?X_letter=J">J</a>
<a href="req.html?X_letter=K">K</a>
<a href="req.html?X_letter=L">L</a>
<a href="req.html?X_letter=M">M</a>
<a href="req.html?X_letter=N">N</a>
<a href="req.html?X_letter=O">O</a>
<a href="req.html?X_letter=P">P</a>
<a href="req.html?X_letter=Q">Q</a>
<a href="req.html?X_letter=R">R</a>
<a href="req.html?X_letter=S">S</a>
<a href="req.html?X_letter=T">T</a>
<a href="req.html?X_letter=U">U</a>
<a href="req.html?X_letter=V">V</a>
<a href="req.html?X_letter=W">W</a>
<a href="req.html?X_letter=X">X</a>
<a href="req.html?X_letter=Y">Y</a>
<a href="req.html?X_letter=Z">Z</a>

II. Решение 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"
    xmlns:my="my:my" exclude-result-prefixes="xs my"
    xmlns="http://www.w3.org/1999/xhtml">
    <xsl:output omit-xml-declaration="yes" method="xhtml" indent="yes"/>

    <xsl:param name="pStart" as="xs:integer" select="65"/>
    <xsl:param name="pEnd" as="xs:integer" select="90"/>

    <xsl:variable name="vCodes" as="xs:integer*" select=
     "for $i in $pStart to $pEnd
       return $i
     "/>

 <xsl:template match="/">
   <html>
       <xsl:sequence select="my:alphabet()"/>
   </html>
 </xsl:template>

 <xsl:function name="my:alphabet" as="element()*">
  <xsl:for-each select="$vCodes">
    <xsl:variable name="vChar" select="codepoints-to-string(.)"/>
    <a href="req.html?X_letter={$vChar}">
     <xsl:sequence select="$vChar"/>
    </a>
  </xsl:for-each>
 </xsl:function>
</xsl:stylesheet>
0 голосов
/ 27 ноября 2011

XSLT 2.0 имеет функцию codepoints-to-string(). Со многими процессорами XSLT 1.0 должно быть достаточно легко реализовать ту же функцию, что и функцию расширения, хотя это сделает ваш код зависимым от этого процессора.

0 голосов
/ 26 ноября 2011

Как предполагает Мартин, было бы лучше избегать отключения-вывода-экранирования. Вам это тоже не нужно, если вы будете удовлетворены простым символом ascii вместо числовой ссылки на символ. Если это так, вы можете использовать подстроку и строку поиска алфавита следующим образом:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:variable name="alphabet" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>

    <xsl:template name="alphabet"> 
        <xsl:param name="iLetter" select="65"/> 
        <xsl:if test="$iLetter &lt; 91"> 
            <a>
                <xsl:attribute name="href">req.html?X_letter=<xsl:value-of select="substring($alphabet, $iLetter - 64, 1)"/></xsl:attribute>
                <xsl:value-of select="substring($alphabet, $iLetter - 64, 1)"/>
            </a> 
            <xsl:call-template name="alphabet"> 
                <xsl:with-param name="iLetter" select="number($iLetter)+1"/> 
            </xsl:call-template> 
        </xsl:if> 
    </xsl:template> 

    <xsl:template match="/">
        <xsl:call-template name="alphabet"/> 
    </xsl:template>
</xsl:stylesheet> 

Ура! * * 1004

0 голосов
/ 26 ноября 2011

Внутри содержимого элемента a вы можете отключить экранирование выходных данных, как в

<a href="req.html?X_letter={$iLetter}">
  <xsl:value-of select="concat('&amp;#', $iLetter, ';')" disable-output-escaping="yes"/>
</a>

Однако этот подход не работает в узлах атрибутов, поэтому я оставил эту часть для передачи кода символа, а не символа.

Также имейте в виду, что отключение-вывод-экранирование - это дополнительная функция сериализации, которая не поддерживается всеми процессорами XSLT, например, встроенный в Firefox / Mozilla процессор XSLT не сериализует дерево результатов, а просто отображает его.так что подход не сработает.

...