Login or Sign up Help | Site Map
Connecting Tech Pros Worldwide

xsl:include with a computed filename

Question posted by: Simon Brooke (Guest) on June 27th, 2008 07:07 PM
I'm trying to do internationalisation by using xsl:include to include
a different file depending on the locale setting, and I'm completely
failing.

I've tried several different approaches:


<xsl:include href="concat( 'i18n-', $locale, '-include.xslt)"/>

fails with XSLT compile error: FileNotFoundException
---------------------
Could not find file 'C:\Projects\ADL\transforms01\concat( 'i18n-',
$locale, '-include.xslt)'.


<xsl:include>
<xsl:attribute name="href">
<xsl:value-of select="concat( 'i18n-', $locale, '-include.xslt)"/>
</xsl:attribute>
</xsl:include>

fails with 'Missing mandatory attribute'


<xsl:param name="i18n-include" select="i18n-en-GB-include.xslt"/>

<xsl:include href="$i18n-include"/>

fails with XSLT compile error:.FileNotFoundException
---------------------
Could not find file 'C:\Projects\ADL\transforms01\$i18n-include'.


xsl:choose is not a valid child of xsl:stylesheet, so I can't do at
top level

<xsl:choose>
<xsl:when test="$lang='en-GB'">
<xsl:include href='i18n-en-GB-include.xslt'/>
</xsl:when>
</xsl:choose>

I'm running out of ideas. If anyone has successful recipes for
conditional include in XSL I'd love to hear them.
Would you like to answer this question?
Sign up for a free account, or Login (if you're already a member).
Bjoern Hoehrmann's Avatar
Bjoern Hoehrmann
Guest
n/a Posts
June 27th, 2008
07:07 PM
#2

Re: xsl:include with a computed filename
* Simon Brooke wrote in comp.text.xml:
Quote:
Originally Posted by
>I'm trying to do internationalisation by using xsl:include to include
>a different file depending on the locale setting, and I'm completely
>failing.
>
>I've tried several different approaches:
>
> <xsl:include href="concat( 'i18n-', $locale, '-include.xslt)"/>


You would have to use { ... } for an attribute value template, but in
XSLT 1.0 the href attribute does not take an attribute value template.
Quote:
Originally Posted by
> <xsl:include>
> <xsl:attribute name="href">
> <xsl:value-of select="concat( 'i18n-', $locale, '-include.xslt)"/>
> </xsl:attribute>
> </xsl:include>


The xsl:attribute element applies only to result elements, I think.
Quote:
Originally Posted by
> <xsl:include href="$i18n-include"/>


See above.
Quote:
Originally Posted by
>xsl:choose is not a valid child of xsl:stylesheet, so I can't do at
>top level
>
<xsl:choose>
<xsl:when test="$lang='en-GB'">
<xsl:include href='i18n-en-GB-include.xslt'/>
</xsl:when>
</xsl:choose>


Indeed.

What you want to do is not supported by XSLT 1.0. It might be wise to
separate the transformation code and the localized text, then you could
use e.g. the document() function to include the localized text.
--
Björn Höhrmann · mailto:bjoern@hoehrmann.de · http://bjoern.hoehrmann.de
Weinh. Str. 22 · Telefon: +49(0)621/4309674 · http://www.bjoernsworld.de
68309 Mannheim · PGP Pub. KeyID: 0xA4357E78 · http://www.websitedev.de/

Richard Tobin's Avatar
Richard Tobin
Guest
n/a Posts
June 27th, 2008
07:07 PM
#3

Re: xsl:include with a computed filename
In article <5ec7e828-f05a-4d79-b061-fcd1c73da416@i76g2000hsf.googlegroups.com>,
Simon Brooke <stillyet@googlemail.comwrote:
Quote:
Originally Posted by
>I'm trying to do internationalisation by using xsl:include to include
>a different file depending on the locale setting, and I'm completely
>failing.
>
>I've tried several different approaches:
>
>
> <xsl:include href="concat( 'i18n-', $locale, '-include.xslt)"/>


As Bjoern says, you can't do that. <xsl:includeis a compile-time
inclusion, like #include in C. XSLT 1.0 doesn't have any dynamic
features of that kind, though EXSLT has a dyn:evaluate function
for (effectively) compiling an XPath at run-time.

Can you parametrise your internationalisation so that you dynamically
select data rather than code?

-- Richard
--
In the selection of the two characters immediately succeeding the numeral 9,
consideration shall be given to their replacement by the graphics 10 and 11 to
facilitate the adoption of the code in the sterling monetary area. (X3.4-1963)

Simon Brooke's Avatar
Simon Brooke
Guest
n/a Posts
June 27th, 2008
07:07 PM
#4

Re: xsl:include with a computed filename
On May 26, 3:53*pm, rich...@cogsci.ed.ac.uk (Richard Tobin) wrote:
Quote:
Originally Posted by
In article <5ec7e828-f05a-4d79-b061-fcd1c73da...@i76g2000hsf.googlegroups.com>,
Simon Brooke *<still...@googlemail.comwrote:
>
Quote:
Originally Posted by
I'm trying to do internationalisation by using xsl:include to include
a different file depending on the locale setting, and I'm completely
failing.

>
Quote:
Originally Posted by
I've tried several different approaches:

>
Quote:
Originally Posted by
* *<xsl:include href="concat( 'i18n-', $locale, '-include.xslt)"/>

>
As Bjoern says, you can't do that. *<xsl:includeis a compile-time
inclusion, like #include in C. *XSLT 1.0 doesn't have any dynamic
features of that kind, though EXSLT has a dyn:evaluate function
for (effectively) compiling an XPath at run-time.
>
Can you parametrise your internationalisation so that you dynamically
select data rather than code?


[Hi Richard, long time no see]

Thanks to you both.

The problem with i18n is not the languages and cultures with which we
are familiar, but extension to languages and cultures with which we
are not. In particular, with making a framework which has enough
flexibility to extend to languages and cultures with which we are not.
For example, the indefinite article:

<xsl:template name="i18n-indefinite-article">
<!-- a string, presumed to be a noun- e.g. the name of a domain
entity -->
<xsl:param name="noun"/>
<xsl:variable name="initial" select="substring( $noun, 1, 1)"/>
<xsl:choose>
<xsl:when test="$initial = 'A' or $initial = 'a'">
<xsl:value-of select="concat( 'an ', $noun)"/>
</xsl:when>
<xsl:when test="$initial = 'E' or $initial = 'e'">
<xsl:value-of select="concat( 'an ', $noun)"/>
</xsl:when>
<xsl:when test="$initial = 'I' or $initial = 'i'">
<xsl:value-of select="concat( 'an ', $noun)"/>
</xsl:when>
<xsl:when test="$initial = 'O' or $initial = 'o'">
<xsl:value-of select="concat( 'an ', $noun)"/>
</xsl:when>
<xsl:when test="$initial = 'U' or $initial = 'u'">
<xsl:value-of select="concat( 'an ', $noun)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat( 'a ', $noun)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>

In English, the indefinite article prefixes the noun to which it
applies; in many Scandinavian languages is postfixes the noun; and in
most Slavonic languages it is missing altogether. English also
demonstrates special cases - the indefinite article used depends on
whether the noun has an initial vowel. Or again, consider plurals:

<xsl:template name="i18n-plural">
<!-- a string, presumed to be a noun -->
<xsl:param name="noun"/>
<xsl:choose>
<xsl:when test="$noun='Person'">People</xsl:when>
<!-- add other special cases here -->
<xsl:when test="starts-with( substring($noun, string-
length($noun) ), 's')">
<xsl:value-of select="concat( $noun, 'es')"/>
</xsl:when>
<xsl:when test="starts-with( substring($noun, string-
length($noun) ), 'y')">
<xsl:value-of select="concat( substring( $noun, string-
length($noun)), 'ies')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat( $noun, 's')"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>

In British English - and, I'm sure, in many other languages - this is
a mess of special cases.

If internationalisation were simply a matter of a lookup table which
returned fixed boilerplate strings, then the document() solution would
work. And if anyone could suggest a (reasonably efficient) way in
which things like indefinite article rules could be encoded as pure
data then that would interest me greatly. But I think that to do the
things I need to do I need the flexibility of having code - so that
people coming after me who write the internationalisation code for
other locales with which I'm completely unfamiliar have enough
richness to do what they need to do.

The alternate solution I can see is to do a two-phase transformation,
where the first transformation builds an xslt stylesheet with the
correct internationalisation data in it and the second transformation
builds the end-user document... which I can do, since this is a
transformation which gets run at build time not at run time, so
performance is not critical. I'm sort of glad I hadn't missed
anything, but I'm sorry there isn't a more elegant solution.

 
Not the answer you were looking for? Post your question . . .
182,398 Experts ready to help you find a solution.
Sign up for a free account, or Login (if you're already a member).

  • Didn't find the answer you were looking for?
    Post Your Question
  • Top Community Contributors