Hi Alice,
While trying to understand what you are after, while trying to interpret
your code, it seems that you want a structure like the following:
if $image_src has a length of 4 or 5, use the whole @url
if $image_src has a length of 6, use the first 4 characters of @url
$image_src and @url are the same
@url is always a number (not sure, but I guess that from your text).
You have a match for the element 'graphic'. Inside it, you construct an
img html tag (img element). Instead of writing extensive xsl:when
statements, you can easier maintain your code when you place it inside
matching templates. In addition, you may want to use attribute value
templates, which is a shorthand for writing attributes. It will look
something like this.
<!-- generic case -->
<xsl:template match="graphic">
<img src="images/{@url}.gif" alt="Picture No. {@url}" />
</xsl:template>
<!-- specific case, 6 or more digits -->
<xsl:template match="graphic[number(@url) > 99999]">
<img src="images/{substring(@url, 1, 4)}" alt="Picture No.
{substring(@url, 1, 4)}" />
</xsl:template>
In general, when doing XSLT, you decide on the most generic match as a
"fits all" and "catch all". Then you create special rules for the
exception cases. In the example above: the general rule (your
xsl:otherwise in xslt) is the one that matches "graphic", the special
rules are the ones that need special treatment. I.e., when the string is
too long.
In your code you have three specific cases. If that is necessary, you
can replace the above with the following, but you must be certain that
your source data is correct. I added the general case as exception: if
your rules do not match, you show an error:
<!-- unknown image found -->
<xsl:template match="graphic">
<xsl:message terminate="yes">Illegal picture found with
url:<xsl:value-of select="@url" /></xsl:message>
</xsl:template>
<!-- specific case: 4 or 5 digits -->
<xsl:template match="graphic[@url > 999 and @url < 100000]">
<img src="images/{@url}.gif" alt="Picture No. {@url}" />
</xsl:template>
<!-- specific case, 6 digits -->
<xsl:template match="graphic[string-length(@url) = 6]">
<img src="images/{substring(@url, 1, 4)}" alt="Picture No.
{substring(@url, 1, 4)}" />
</xsl:template>
As you see, it is very easy to maintain this code: just add more rules
to it. If you need more processing, add the appropriate
<xsl:apply-templates /> and/or appropriate matching templates. Whenever
you find yourself writing an extension xsl:choose statement based on
something that you can do with predicates, in 90% of the situation
(debatable of course) it will be more readable and less error prone to
do it with matching template.
The difference: in your method, you have to think of every scenario,
telling the processor what to do and you are programming as if you are a
C/VB/PHP/Java etc programmer (leading to more code), the other method is
where xslt shines and you let the processor pick out the correct rules
for you based on the input tree (leading to less code). This is called
declarative programming and the push vs. pull model (but I never know
which one is which, so I decided to use the more familiar "applying
templates and matching templates" against "traditional imperative
programming style with if/switch/case/when etc").
Good luck with coding in XSLT!
Cheers,
-- Abel Braaksma
Alice Ju-Hsuan Wei wrote:
Thanks to Michael and Jing. This part is now working and prints out
the "value of the string length" accurately.
However, when I tried to use the node with the result of "123456," it
prints out the "string-length" as a 6 preperly. But when I try to run
a "test" of action according to this result, it does not perform any
of the actionsth as in <xsl:when test="string-length($image_src_
='6'">, but performs the actions as in
<xsl:when-test="string-length($image_src)='4' or '5'"> as shown below:
<xsl:when test="string-length($image_src) = '4' or '5'">
<img>
<xsl:attribute name="src">images/<xsl:value-of
select="./@url"/>.gif</xsl:attribute>
<xsl:attribute name="alt"> Picture No.
<xsl:value-of select="./@url"/>
</xsl:attribute>
</img>
</xsl:when>
<xsl:when test="string-length($image_src) = '6' ">
<img>
<xsl:attribute name="src">images/<xsl:value-of
select="substring($image_src,1,4)"
/>.gif</xsl:attribute>
<xsl:attribute name="alt"> Picture No.
<xsl:value-of select="substring($src,1,4)"/>
</xsl:attribute>
</img>
</xsl:when>
Does anyone know if there is something I should have done that I have
not?
Thank again.