views:

730

answers:

2

I am using XSL transform on XML. Some part of transform are dependent on current locale. Is there any way to find the current locale from within XSL?

For example, the user-visible serialization of a floating point number can vary between locales ("1.0" in English is "1,0" in German), and my transform needs to take differences like these into account.

+2  A: 

Pass it in as a parameter.

<xsl:param name="CultureInfo" select="'default'" />

Place an XSL param on the top level of your stylesheet, and set it from "outside" before you invoke the stylesheet.

The other (proprietary) way would be to register extension functions and ask from within the stylesheet.

Tomalak
There is no way to pass the parameters. There is one xml and one xsl; thats it.
Ramesh Soni
And what is your XSLT processor?
Tomalak
One xml and one xsl can still accept parameters. I can think of no scenario in which there would be "no way to pass parameters" to an XSL.
Cerebrus
Being able to pass in parameters is not strictly required by the spec, IIRC. Some environments or setups may make it impossible to do so. XML with integrated XSLT for transformation in the browser may be such a case.
Tomalak
Sorry, but I have never heard of such a setting where a parameter can't be passed in, even XSLT through a browser. Some more info from OP about his environment is most welcome. The whole "culture" thing still is a big mystery, after he "explained" it, so not much hope for a solution yet is there? :)
AlexanderJohannesen
@AlexanderJohannesen: For example: http://www.w3schools.com/xsl/xsl_transformation.asp, see "Link the XSL Style Sheet to the XML Document". I'm not sure if you can pass in parameters in such a setup.
Tomalak
Well, there's things like <?modxslt-param name="variable" value="its value" ?> but yes, it's getting trickier. I'm sure there's a JS trick to get the value dynamic or populated with browser environment stuff, but we're moving far, far away from both reality and sanity. In that case it's probably not that easy. You win. :)
AlexanderJohannesen
@AlexanderJohannesen: No need to escape pointy brackets in comments, they'll show up all right.
Tomalak
+2  A: 

Locals aren't natively supported in XSLT 1.0, but there are ways to work with them, but you need to pass it in as a parameter to your XSLT processor or rely on extensions. Some processors will grant you access to the locale information, but there is no standard way of doing it, and we must know your environment to see if it is possible. However, in XSLT 2.0 some of the date, time and number formatting functions will have (sometimes limited) support for locales, and will be handled by the processor, not by you (which is why there's these functions :)

As to using some form of locality in a XSLT 1.0 environment and partially as a Good Thing (TM) regardless of XSLT version, I'd set up a few basic templates for the type of data you're working with, and pass the local parameter in (as explained before). For numbers, look for the xsl:format-number, for example.

As to other local things, I'd create another XML file, and let the parameter work as a picker for the info you're after. The XML might look like;

<locals>
   <config id="de">
     <currency notation="&#8352;" format-number="###.###,##" />
     <text id="welcome">Wilcommen!</text>
   </config>
   <config id="en">
     <currency notation="&#163;" format-number="### ###.##" />
     <text id="welcome">Welcome!</text>
   </config>
   <config id="no">
     <currency notation="NOK" format-number="###.###,##" />
     <text id="welcome">Velkommen!</text>
   </config>
</locals>

From this, open it as ;

<xsl:variable name="locale" select="document('locale.xml')/locals/config[@id=$parameter.for.locale]" />

And you can use it as such for the welcome text;

<xsl:value-of select="$locale/text[@id='welcome']" />

For number formatting and such it's a bit more complex, but verify this is the right path first and I'll expand, but basically you should make a few keys over the locale XML file, and use a key lookup for values. For numbers and such (need to tell me more about what you want to support) I'd write a couple of templates that deal with that, and use ;

<xsl:call-template name="my-template">
   <xsl:with-param name="this" select="'some_number'" />
</xsl:call-template>
AlexanderJohannesen
+1 for the good answer!
Dimitre Novatchev