tags:

views:

51

answers:

2

I doing the right transformations to develop a multilingual website. All the text of this website needs to be taken from an XML file because the output of the site will be the processed file.

This are the basic files, index.xml:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="xsl/index.xsl"?>
<page>
    <entry>
        <id>12</id>
        <value>img/12.jpg</value>
    </entry>
    <entry>
        <id>13</id>
        <value>img/13.jpg</value>
    </entry>
</page>

This entries are unique so they didn't need to be translated. My index.xsl:

<?xml version="1.0" encoding="UTF-8"?>   
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
    <!-- I'm including a language file, but I've various language files that will be stored in different folders -->
    <xsl:param name="menu" select="document('../lang/index.xml')" />

    <xsl:template match="/">
        <html>
            <xsl:attribute name="lang"><!-- name of the lang --></xsl:attribute>

            <head></head>

            <body>
                <ul id="menu">
                    <xsl:for-each select="language/menu">
                        <li><xsl:value-of select="." /></li>
                    </xsl:for-each>
                </ul>

                <!-- this is not important, is an example -->
                <xsl:for-each select="page/entry">
                    <xsl:value-of select="id" />
                </xsl:for-each>
            </body>
        </html>
    </xsl:template>
</xsl:stylesheet>

I include ../lang/index.xml which contains all the words in some language, for example English. I need this site in 3 different languages that can be stored like:

/lang/en/index.xml

<language>
    <menu>Home</menu>
    <menu>Images</menu>
</language>

/lang/es/index.xml

<language>
    <menu>Inicio</menu>
    <menu>Imágenes</menu>
</language>

/lang/fr/index.xml

<language>
    <menu>Maison</menu>
    <menu>Images</menu>
</language>

My question is how I can manage this. I've no option to change that, because I'm not allowed to do a specific index.xsl file for each language.

Thank you in advance and sorry for school English.

+1  A: 

Language specific input file:

This file is to be transformed. In addition to the stylesheet processing instruction it also passes the actual language as a parameter to the stylesheet.

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="xsl/index.xsl"?>
<?xm-xsl-param name="lang" value="en"?>
<page>
  <entry>
    <id>11</id>
    <value>bla </value>
  </entry>
  <entry>
    <id>14</id>
    <value>bla bla</value>
  </entry>
</page>

Language independent file

This file gets included using the document function. Note that this does not need a stylesheet processing instruction:

<?xml version="1.0" encoding="UTF-8"?>
<page>
    <entry>
        <id>12</id>
        <value>Lorem ipsum</value>
    </entry>
    <entry>
        <id>13</id>
        <value>Lorem ipsum</value>
    </entry>
</page>

XSL transformation:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;

  <!-- the external parameter with a default value -->
  <xsl:param name="lang" select="en" />

  <xsl:variable name="entries" 
                select="page/entry | document('../lang/index.xml')/page/entry" />


  <xsl:template match="/">
    <html lang="{$lang}">
      <head></head>

      <body>
        <!-- accessing an entry by its id value -->
        <xsl:value-of select="$entries[id = 12]/value"/>

        <!-- looping all entries -->
        <xsl:for-each select="$entries">
          <xsl:sort select="id" order="ascending"/>
          <xsl:value-of select="id" />
        </xsl:for-each>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>
0xA3
@0xA3: You aren't using the $lang parameter for anything useful -- seems like an error. I would expect to see that particular text is retrieved and output from a corresponding language specific file.
Dimitre Novatchev
@Dimitre Novatchev: The question is how these transformations are run. The OP is not very clear about this. Usually you would add the processing instruction if you want to render the XML in a browser, and then users would probably access language specific URLs like http://example.com/index.fr.xml to access the French version. But maybe the scenario here should be a totally different one. Maybe I should have made the assumptions I made in my answer a bit clearer. Of course, in my version the $lang parameter is not really needed and more of a gimick.
0xA3
I've updated the answer with a more clarify example on what I'm looking for. I'm processing the files via PHP on the server, the client receive the final XHTML output. Thanks in advance!
Isern Palaus
+1  A: 

This stylesheet:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
    <xsl:output method="xml"/>
    <xsl:param name="pLang" select="'es'"/>
    <xsl:param name="pMenu" 
               select="document(concat('../lang/',$pLang,'/index.xml'),/)"/>
    <xsl:template match="/">
        <html lang="{$pLang}">
            <head></head>
            <body>
                <ul id="menu">
                    <xsl:apply-templates select="$pMenu/*"/>
                </ul>
                <xsl:apply-templates select="page/entry"/>
            </body>
        </html>
    </xsl:template>
    <xsl:template match="language/menu">
        <li>
            <xsl:value-of select="." />
        </li>
    </xsl:template>
    <xsl:template match="entry">
        <img id="{id}" src="{value}"/>
    </xsl:template>
</xsl:stylesheet>

Output:

<html lang="es">
    <head></head>
    <body>
        <ul id="menu">
            <li>Inicio</li>
            <li>Imágenes</li>
        </ul>
        <img id="12" src="img/12.jpg" />
        <img id="13" src="img/13.jpg" />
    </body>
</html>
Alejandro
@Alejandro thanks another time for your answers!! What I don't understand is the $pMenu param. In this xml/xsl examples I write down a few lines, but it will be much more. The /lang/<language>/index.xsl file will have the same structure for each language. I've to use param's for each of it? I wish it's clear... as you can see my English... Thank you another time!
Isern Palaus
@Isern Palaus: I think that you want to output three diferent pages. Or have I missed something? Whenever you want to output a page you can run a transformation passing language parameter to your XSLT processor. If you want to output the three pages at once, then you must run an XSLT 2.0 processor or use some extension element...
Alejandro
@Alejandro You're so right. I only want to output a page. I've loaded the two .xml files (the index.xml and the index.xml that corresponds with the languages values) and then used the .xsl. I've all it working! Thank you!
Isern Palaus
@Isern Palaus: You are wellcome! Ask any time.
Alejandro