Presents your XML E-NEWSLETTER for February 5, 2003 <-------------------------------------------> USE XML TO CREATE INTERNATIONAL APPLICATIONS, PART 1 There are two major issues to confront when you're creating international XML solutions. The first is to deliver alternate languages to users. The second hurdle is that you not only need to translate the text of your application but also the actual encoding of the characters for the particular language. TRANSLATION On the surface, translation seems simple enough--you translate this language into that one, and voila, you're done. It's not that easy. There are many items you may want to translate, with the most obvious being the content. Less obvious is that you may need to translate the actual element names. A common approach to translation is to put all of the text in a resource file that lives outside your application. Traditionally, developers have used property files to manage resources; however, property files are not the only solution. Another approach involves placing the resource text into an XML document. For example, LISTING A shows a simple set of resources described using XML: Listing A: resources.xml Welcome to my website Bienvenue a mon website Willkommen zu meinem website Submit Soumettez Reichen Sie ein Ignoring my bad French and German language skills, you see that each component that needs to be translated is identified as a text resource. The id attribute uniquely identifies the resource to the application. In this case, the resource identifiers are in English, but they could be in any language. Another approach is to use separate resource files for each language. For example, LISTING B shows a specific resource file for Spanish. Listing B: resources-spanish.xml Recepcion a mi website Someta ENCODING Beyond translating the text or content of your applications, you will also need to understand how to deliver text in different languages. For example, you may not be familiar with the multitude of other character sets used to describe other languages. To handle the problems of encoding and locale, you can create another XML file for your application. LISTING C shows how to describe the various languages your application supports, along with their associated top-level domains (TLD) and their associated character sets. This example happens to show three languages all based on the same ISO-8859-1 character set: Listing C: encoding.xml English .us .uk .ca ISO-8859-1 French .fr .ca ISO-8859-1 German .de ISO-8859-1 XML SOLUTIONS Using the XML examples above, you can start delivering international applications. However, there are still some additional considerations. The first is how to actually perform the translation. You could dynamically generate Web pages on the fly for each user. To do so, you might examine both the TLD of the user's address as well as the Accept-Language HTTP header. These could be used to determine whether you support the user's language and to locate the appropriate character encoding from the XML document. You could then generate the requested page by pulling the text from the resource's XML document. Another approach would be to batch-translate your application's pages into all of the languages you support. This is more efficient because it means you generate the page only once, and the user doesn't have to wait for it on every page hit. The downside is that it's not dynamic. In other words, as you change your application, you will need to run the batch process to bring your pages up to date. Finally, you could implement a more elegant design that takes advantage of both of these ideas. You would still generate the pages on the fly, but now you would store the translated page in a cache. In fact, you would only translate the page when it's changed. Otherwise, you'd pull it from the cache. This allows you to reap the benefits of efficiency and eliminates the need to run a batch process often. In part two I'll go into more detail and expand on the translation process by showing code that actually presents a page in different languages. Brian Schaffner is a senior consultant for Fujitsu Consulting. He provides architecture, design, and development support for Fujitsu's Telcom360 group. ---------------------------------------- Presents your XML E-NEWSLETTER for February 12, 2003 <-------------------------------------------> USE XML TO CREATE INTERNATIONAL APPLICATIONS, PART 2 In part one, we talked about how to use XML to facilitate multiple languages on a Web page. In part two, we'll take the discussion a little further and illustrate a working example. STARTING AT THE END To make the concept a little easier, we'll start at the end so that you get some idea of what we're trying to achieve. We want to create a simple HTML page that can be displayed in multiple languages. LISTING A shows our page with English text: Listing A: login.html Sample Application

Welcome to the Sample Application


Thank you for using our application. To begin, please log in below by providing your username and password.

Username:
Password:
The first step is to extract the English text from this page and put it into a resource file. Then, we'll put the HTML page into an XSL style sheet. From there, we'll create a second resource file for a new language, in this case Spanish. Finally, we'll apply some Java code to a JSP to make it all work. THE RAW MATERIALS First, we extract the text and create our resource file, as shown in LISTING B, and then create the style sheet, shown in LISTING C. Listing B: resources-english.xml Sample Application Welcome to the Sample Application Thank you for using our application. To begin, please log in below by providing your username and password. Username Password Log in Listing C: login.xsl <xsl:value-of select="/Resources/TextResource[@id='Title']" />




:
:
Next, we need to create our alternate language resources. There are a variety of ways you can go about doing this, including hiring a translator, translating the text yourself, or using an automated tool such as AltaVista's Babel Fish interface. Our Spanish resources are shown in LISTING D: http://world.altavista.com/ Listing D: resources-spanish.xml Programa de Muestra Recepcion a la Programa de Muestra Gracias por usar nuestro programa. Para comenzar, satisfacer la conexion abajo proporcionando su nombre y contrasena. Nombre Contrasena Conecte GLUE IT TOGETHER WITH JAVA Now that we have all the raw materials, we need to put them together. Because this is a Web application, we'll use Java Server Pages running on Apache's Tomcat server. Instead of making an HTTP request for "login.html", users will request "login.jsp". The JSP file will perform the translation, cache the results, and return the end product HTML page to the user. LISTING E shows our login.jsp page: Listing E: login.jsp <%@ page import="java.util.*, java.io.*, javax.xml.transform.*, javax.xml.transform.stream.*, java.net.*"%> <%! private String getLanguage(HttpServletRequest request) { String retval = ""; String header; Enumeration enum; enum = request.getHeaderNames(); while (enum.hasMoreElements()) { header = (String) enum.nextElement(); if (header.equals("accept-language")) { retval = request.getHeader(header).substring(0, 2); break; } } return retval; } private String getResourceFilename(String language) { // typically, this process would use encoding.xml // to locate the appropriate resource doc if (language.equals("es")) return "resources-spanish.xml"; else return "resources-english.xml"; } %> <% String rootdir = "file:C:\\Program Files\\Apache Group\\Tomcat 4.1\\webapps\\ROOT\\"; String language; String resourcefile; String cachefile; String includefile; String xslfile = rootdir + "login.xsl"; File fp; language = getLanguage(request); includefile = "/cache/login-" + language + ".html"; cachefile = "C:\\Program Files\\Apache Group\\Tomcat 4.1\\webapps\\ROOT\\" + includefile; fp = new File(cachefile); if (!fp.exists()) { try { resourcefile = rootdir + getResourceFilename(language); TransformerFactory tFactory = TransformerFactory.newInstance(); Transformer transformer = tFactory.newTransformer(new StreamSource(new URL(xslfile).openStream())); transformer.transform(new StreamSource(new URL(resourcefile).openStream()), new StreamResult(new FileOutputStream(cachefile))); } catch (Exception e) { out.print("Exception translating XSL stylesheet: " + e.getMessage()); } } %> There may appear to be a lot going on in the JSP, but there's really not. The top section defines the page parameters and the two methods we'll use within our page. The basic flow is this: * Get user's language preference from HTTP accept-language header via the getLanguage() method. * Look in the cache directory to see if we have cached this page previously. * Determine the appropriate resource file based on the language via the getResourceFilename() method. * Transform the login.xsl file using the resource file and store in the cache directory. * Return the translated file from the cache directory. RUNNING THE SAMPLE Install the above files in Tomcat's webapps/ROOT directory, and then create a subdirectory under webapps/ROOT called cache. When you make a request to http://localhost/login.jsp, Tomcat will compile the JSP and run it. If all goes well, and your browser is configured for English as the default, you will see the page in English. To see the translation, you need to configure your browser for Spanish. Using Internet Explorer, select Internet Options from the Tools menu and then click on Languages. Add a Spanish language and move it above English so that it has preference. Now reload your login page and you should see it in Spanish instead of English. Brian Schaffner is a senior consultant for Fujitsu Consulting. He provides architecture, design, and development support for Fujitsu's Telcom360 group. ----------------------------------------