Building dynamically localised applications is a real cinch with XForms. This article describes one approach to doing it.
Let's assume that you already have an application that you want to localise. For the sake of this demonstration, we'll use a simple form that requests a user's name:
<xf:model> <xf:instance id="instData"> <data xmlns=""> <name1>Phil</name1> <name2>Booth</name2> </data> </xf:instance> </xf:model> <xf:input ref="instance('instData')/name1"> <xf:label>First name</xf:label> </xf:input> <xf:input ref="instance('instData')/name2"> <xf:label>Surname</xf:label> </xf:input>
Now let's say that you want to translate this application into French. What steps do you need to take to achieve that?
The first thing that you must do is move all of your labels into their own instance:
<xf:instance id="instLabels"> <labels xmlns=""> <locale id="en"> <name1>First name</name1> <name2>Surname</name2> </locale> </labels> </xf:instance>
You can see that the labels have been placed inside a container that identifies their locale. Storing them in a structure like this makes it easy to add translations for as many different locales as neccessary. Here is the same instance, with translations added for the French locale:
<xf:instance id="instLabels"> <labels xmlns=""> <locale id="en"> <name1>First name</name1> <name2>Surname</name2> </locale> <locale id="fr"> <name1>Prénom</name1> <name2>Nom</name2> </locale> </labels> </xf:instance>
With the labels instance in place, the next thing that's required is a way for the user to select their preferred locale. A select1 control is a good candidate for doing that. First, an instance is required to store the current locale selection:
<xf:instance id="instState"> <state xmlns=""> <locale>en</locale> </state> </xf:instance>
Then, a select1 control is needed to allow the user to make that selection:
<xf:select1 ref="instance('instState')/locale" appearance="full"> <xf:item> <xf:label>English</xf:label> <xf:value>en</xf:value> </xf:item> <xf:item> <xf:label>Français</xf:label> <xf:value>fr</xf:value> </xf:item> </xf:select1>
All that is left now is to link up the label elements from the input controls to the labels instance, indexed by the id of the currently selected locale. The XForms model will then automatically ensure that the input labels get refreshed appropriately, every time the user updates their locale:
<xf:input ref="instance('instData')/name1"> <xf:label ref="instance('instLabels')/locale[@id = instance('instState')/locale]/name1" /> </xf:input> <xf:input ref="instance('instData')/name2"> <xf:label ref="instance('instLabels')/locale[@id = instance('instState')/locale]/name2" /> </xf:input>
| Attachment | Size |
|---|---|
| enfr.png | 16.82 KB |

The problem with this
The problem with this approach is complex XPath expressions in the ref attributes as well as loading all language labels even though they might not be needed at all.
In my opinion, a more elegant solution would have a ui-instance containing only labels of the selected language. If the UI language is changed, then the content of that instance will be replaced (using xforms:submission) with the labels of the newly selected language. This approach solves both issues pointed above.
Kind regards
-Markku
Yes, it's a good example of
Yes, it's a good example of XForms potential.
Let me give you small comments about it :
Thank you again!
-Alain
agenceXML
XSLTForms
Bordeaux, France