Используя XSLT, как мне увеличить значение атрибута 'format' для <xsl: number> (например, 'a' + 1 = 'b')? - PullRequest
1 голос
/ 10 августа 2011

В содержимом элемента моего исходного XML-файла есть 2321 вхождение символа 'a'.

Мне удалось получить это число, но я могу сделать это только для символа «а». Мне нужно получить вхождения для всех букв алфавита.

См. Код:

Используется для распечатки элемента TextBlock:

<xsl:template name="get-textblock">

    <xsl:param name="letter-one"/>
    <xsl:param name="letter-two"/>
    <xsl:param name="letter-one-f"/>
    <xsl:param name="letter-two-f"/>

    <xsl:if test="$letter-one">
        <xsl:number value="$letter-one" format="$letter-one-f"/>
    </xsl:if>

    <xsl:if test="$letter-two">
        <xsl:number value="$letter-two" format="$letter-two-f"/>
    </xsl:if>

</xsl:template>

Затем в этом рекурсивном цикле я распечатываю, сколько раз встречается «a» или «A», используя выражение XPath и шаблон get-textblock.

<xsl:template name="print-alphabet-value-rows">
    <!-- 'letter' is just a counter. -->
    <xsl:param name="letter" select="1"/>
    <!-- numbers -->
    <xsl:param name="letter-one" select="1"/>
    <xsl:param name="letter-two" select="1"/>
    <!-- format attribute values -->
    <xsl:param name="letter-one-f" select=" 'a' "/>
    <xsl:param name="letter-two-f" select=" 'A' "/>
    <xsl:param name="gridrow">2</xsl:param>
    <xsl:param name="gridcol">2</xsl:param>

    <xsl:call-template name="get-textblock">
        <xsl:with-param name="gridrow" select="$gridrow"/>
        <xsl:with-param name="gridcol" select="$gridcol"/>
        <xsl:with-param name="style">{StaticResource ValueText}</xsl:with-param>
        <xsl:with-param name="letter-one-f" select="$letter-one-f"/>
        <xsl:with-param name="letter-two-f" select="$letter-two-f"/>
        <xsl:with-param name="letter-one" select="$letter-one"/>
        <xsl:with-param name="letter-two" select="$letter-two"/>
        <xsl:with-param name="text">
            <xsl:value-of select="count(/n-grams-sorted/n-gram[starts-with(.,$letter-one-f) or starts-with(.,$letter-two-f) ])"/>
        </xsl:with-param>
    </xsl:call-template>

    <xsl:if test="$letter &lt; 26">
        <xsl:call-template name="print-alphabet-value-rows">
            <xsl:with-param name="gridrow" select="$gridrow + 1"/>
            <xsl:with-param name="letter" select="$letter +1"/>
            <!-- this doesn't work. It prints out the same number of occurrences for all the rows because it only fetches 'a' and 'A', it never increases them -->
            <xsl:with-param name="letter-one" select="$letter-one +1"/>
            <xsl:with-param name="letter-two" select="$letter-two +1"/>
        </xsl:call-template>
    </xsl:if>

Итак, здесь я определяю шаблон get-textblock для рисования элемента TextBlock. Затем я поставляю следующие параметры:

буква : счетчик, который просто идет на 26 строк вниз

letter-one : число, имеющее формат 'a' , прикрепленное к нему

две буквы : число, имеющее формат 'A' , прикрепленное к нему

То, что я хочу сделать, это продолжать увеличивать «a» и «A», чтобы соответствующее выражение XPath читалось как «b» & «B», «c» & «C» и т. Д., Вплоть до последняя буква алфавита. Я не знаю, как это сделать.

Есть идеи? * Спасибо * 1035

Ответы [ 3 ]

1 голос
/ 10 августа 2011

Я не совсем уверен, что понимаю вопрос, но вы можете сделать что-нибудь с чем-то вроде

translate($letter-one, 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ','bcdefghijklmnopqrstuvwxyzaBCDEFGHIJKLMNOPQRSTUVWXYZA')
0 голосов
/ 11 августа 2011

Вот еще один XSLT 1.0 способ сделать это :

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>

 <xsl:variable name="vLower" select=
  "'abcdefghijklmnopqrstuvwxyz'"/>

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

 <xsl:variable name="vDoc" select="document('')"/>

 <xsl:template match="/">
   <xsl:for-each select=
    "($vDoc//node() | $vDoc//@* |$vDoc//namespace::*)
           [not(position() > 25)]
    ">
    <xsl:variable name="vPos" select="position()"/>

    <xsl:variable name="vcurLow" select=
    "substring($vLower,$vPos, 1)"/>

    <xsl:value-of select="concat($vcurLow, ' --> ')"/>

    <xsl:call-template name="incrementLetter">
      <xsl:with-param name="pLetter" select="$vcurLow"/>
      <xsl:with-param name="pAlha" select="$vLower"/>
    </xsl:call-template>
    <xsl:text>&#xA;</xsl:text>
   </xsl:for-each>
 </xsl:template>

 <xsl:template name="incrementLetter">
   <xsl:param name="pLetter"/>
   <xsl:param name="pAlha"/>

   <xsl:value-of select=
"substring($pAlha,
       string-length(substring-before($pAlha,$pLetter))+2,
           1)"/>
 </xsl:template>
</xsl:stylesheet>

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

a --> b
b --> c
c --> d
d --> e
e --> f
f --> g
g --> h
h --> i
i --> j
j --> k
k --> l
l --> m
m --> n
n --> o
o --> p
p --> q
q --> r
r --> s
s --> t
t --> u
u --> v
v --> w
w --> x
x --> y
y --> z
0 голосов
/ 10 августа 2011

Вы не сказали, является ли это XSLT 1.0 или 2.0, но я предполагаю, что это 1.0, потому что в противном случае проблема была бы довольно тривиальной.Но даже в XSLT 1.0 это кажется достаточно простым, если вы готовы выписать алфавит в виде строки.(Я предполагаю, что под «алфавитом» вы подразумеваете английский алфавит из 26 букв.)

...