xsl:include with a computed filename

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Simon Brooke

    xsl:include with a computed filename

    I'm trying to do internationalis ation 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: FileNotFoundExc eption
    ---------------------
    Could not find file 'C:\Projects\AD L\transforms01\ concat( 'i18n-',
    $locale, '-include.xslt)'.


    <xsl:include>
    <xsl:attribut e 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:.FileNotF oundException
    ---------------------
    Could not find file 'C:\Projects\AD L\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.
  • Bjoern Hoehrmann

    #2
    Re: xsl:include with a computed filename

    * Simon Brooke wrote in comp.text.xml:
    >I'm trying to do internationalis ation 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.
    > <xsl:include>
    > <xsl:attribut e 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.
    > <xsl:include href="$i18n-include"/>
    See above.
    >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@h oehrmann.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/

    Comment

    • Richard Tobin

      #3
      Re: xsl:include with a computed filename

      In article <5ec7e828-f05a-4d79-b061-fcd1c73da416@i7 6g2000hsf.googl egroups.com>,
      Simon Brooke <stillyet@googl email.comwrote:
      >I'm trying to do internationalis ation 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:includei s 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 internationalis ation 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)

      Comment

      • Simon Brooke

        #4
        Re: xsl:include with a computed filename

        On May 26, 3:53 pm, rich...@cogsci. ed.ac.uk (Richard Tobin) wrote:
        In article <5ec7e828-f05a-4d79-b061-fcd1c73da...@i7 6g2000hsf.googl egroups.com>,
        Simon Brooke  <still...@googl email.comwrote:
        >
        I'm trying to do internationalis ation 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:includei s 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 internationalis ation 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="substri ng( $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:otherwis e>
        <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='Pe rson'">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:otherwis e>
        <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 internationalis ation 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 internationalis ation 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 internationalis ation 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.

        Comment

        Working...