问题
There are 2321 occurrences of the character 'a' in the element contents of my source XML file.
I have succeeded in obtaining this number, but I can only do it for the 'a' character. I need to obtain the occurrences for all the letters of the alphabet.
See code:
This is used to print out a TextBlock element:
<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>
Then, in this recursive loop I print out how many times 'a' or 'A' occur, using an XPath expression and the get-textblock template.
<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 < 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>
So, what I do here is I define a get-textblock template to draw a TextBlock element. Then, I supply the following parameters:
letter: a counter to simply go 26 rows down
letter-one: a number which has a format 'a' attached to it
letter-two: a number which has a format 'A' attached to it
What I want to do is keep increasing 'a' and 'A', so that the corresponding XPath expression reads 'b' & 'B', 'c' & 'C' etc., all the way down to the last letter of the alphabet. I don't know to accomplish that.
Any ideas? Thanks
回答1:
I'm not totally sure I understand the question, but can you do anything with something like
translate($letter-one, 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ','bcdefghijklmnopqrstuvwxyzaBCDEFGHIJKLMNOPQRSTUVWXYZA')
回答2:
You haven't said whether this is XSLT 1.0 or 2.0, but I assume it's 1.0 because otherwise the problem would be pretty trivial. But even in XSLT 1.0, it seems straightforward enough if you're prepared to write the alphabet out as a string. (I assume by 'alphabet' you mean the English alphabet of 26 letters.)
回答3:
Here is another XSLT 1.0 way of doing this:
<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>
</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>
when this transformation is applied on any XML document (not used), the result shows that any letter is incremented correctly:
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
来源:https://stackoverflow.com/questions/7011714/using-xslt-how-do-i-increase-the-value-of-the-format-attribute-of-an-xslnum