ASPNL logo (1 kb)
Tuesday, September 07, 2010




Microsoft MVP

.NET Codewise Community
<< vorige | overzicht | volgende >>

Meertalige applicaties in ASP(.NET)

Door Tim Musschoot
22 maart 2002

Inleiding

Sinds de opkomst van commerciële website is het fenomeen van meertalige sites aanwezig. Het probleem dat zich stelt bij dergelijke websites is: ‘Hoe zorg je er voor dat met een minimum aan werk en onderhoud een website taalonafhankelijk gemaakt wordt?’ Bij de eerste eenvoudige HTML websites werd dit probleem opgelost door de website in een virtuele directory te plaatsen die de taal aangaf. Voor iedere beschikbare taal werd een kopie van de website gemaakt in de desbetreffende taal. Stel u voor dat u over een site in 5 talen beschikt waarvan u op 3 verschillende pagina’s een wijziging wenst aan te brengen…

Sinds XML algemeen gebruikt wordt heeft men dit probleem enigszins uit de wereld geholpen. Per taal maakt u een apart XML document aan dat enkel de tekstuele inhoud van de site op een gestructureerde manier bevat. Als alternatief bij grote sites maakt men per pagina per taal een apart XML document aan. De layout van de pagina wordt vervolgens door een XSLT document bepaald. Hiermee kan men ervoor zorgen dat de layout voor alle talen identiek is. Een aanpassing van dit XSLT document zal automatisch de wijzigingen voor alle beschikbare talen doorvoeren.

Wanneer u over een site beschikt die gebruik maakt van ASP of ASP.NET functionaliteiten is bovenstaande oplossing via XML niet meer bruikbaar. Dit wil echter niet zeggen dat XML is uitgesloten als mogelijke optie. De oplossing bestaat er in om alle teksten die de gebruiker te zien krijgt (van opschriften op buttons tot volledige beschrijvende teksten) uit een XML bestand te halen. In dit bestand worden de teksten per taalklasse gescheiden. Op het moment dat de pagina serverside wordt opgebouwd, worden de teksten in de juiste taal ingeladen. In de volgende hoofdstukken wordt een oplossing uit de doeken gedaan voor zowel ASP.NET als voor ASP.

ASP.NET

Werking
Voor ASP.NET heb ik een object aangemaakt dat gegevens uit een XML document gaat ophalen. Hieronder vindt u de code (C#). In de bijlage vindt u de VB.NET code.

using System;
using System.Xml;
namespace diffudessnet

{
   public class XmlLang
   {
      protected XmlDataDocument X;
      protected String Lang;

      public XmlLang(String FileName,String Language)
      {
         String Name = "http://localhost/myapp/xml/"+ FileName;
         X = new XmlDataDocument();
         X.Load(Name);           Lang = Language;
      }

      public XmlLang(String FileName)
      {
         String Name = "http://localhost/myapp/xml/"+ FileName; 
         X = new XmlDataDocument();
         X.Load(Name);
         Lang = "N";
      } 

      public String GetString(String Name)
      { 
         XmlNode node;
         node = X.SelectSingleNode("//main/language[@id='"
             + Lang + "']/" + Name);
             
         if (node == null) return "";
         else
         {
            string value = node.InnerXml.ToString();
            return value;
         }
      }
   }
}

Het object beschikt over drie methods:

  • XmlLang::XmlLang(String FileName, String Language)
  • XmlLang::XmlLang(String FileName)
  • String XmlLang::GetString(String Name)

Om te beginnen gaan we ervan uit dat alle XML documenten in eenzelfde directory staan. Op deze manier kunnen ze ontoegankelijk gemaakt worden voor de gebruiker. Dit pad wordt vast gecodeerd in de constructor van dit object. Indien iemand hiervoor een betere oplossing kent, let me know…
In de eerste versie van de constructor geeft men de naam van het XML document aan, en de taal die men wenst te gebruiken. Als naam voor een document is het handig om dezelfde naam als uw ASPX pagina te nemen. De taal is een String met als mogelijke waarden "N", "F", "E", … De structuur van het XML document wordt straks besproken. De tweede versie van de constructor zal automatisch de Nederlandstalige versie van de teksten ophalen. Handig indien u momenteel enkel een Nederlandstalige site wenst. De memberfunctie GetString(String Name) zal de tekst behorende tot het codewoord Name en de gekozen taalinstelling ophalen. Alle tekstitems in het XML document worden geïdentificeerd a.h.v. keywords. De waarde van een keyword is een woord in de gewenste taal.

XML Document
Hieronder vindt u de structuur van het XML document.

<?xml version="1.0" encoding="utf-8" ?>
<main>
   <language id="N">
      <naam>Naam</naam>
      <nummer>Nummer</nummer>
      <straat>Straat</straat> 
      <land>Land</land> 
   </language>
   <language id="E">
      <naam>Name</naam>
      <nummer>Number</nummer>
      <straat>Street</straat>
      <land>Country</land>
   </language>
   <language id="F">
      <naam>Nom</naam>
      <nummer>Numméro</nummer>
      <straat>Rue</straat>
      <land>Pays</land>
   </language>
</main>

De verschillende taalgroepen worden gescheiden door de
<language id="languageid" /> tags. Het is de parameter languageid die men dient mee te geven met de constructor van het object.

Gebruik
Het gebruik van het object is eenvoudig. In de OnInit(…) memberfunctie van uw pagina object creëert u een nieuwe instantie van dit object. Stel dat we een pagina client.aspx hebben die klantgegevens bevat. De naam van de codebehind file is client.aspx.cs. De naam van het XML bestand is dan client.xml.

override protected void OnInit(EventArgs e)
{
   InitializeComponent(); 
   base.OnInit(e);

   XmlLang Lang = new XmlLang("client.xml",Session["LANGUAGE"].ToString());

   this.NaamLabel.Text = Lang.GetString("naam");
   this.StraatLabel.Text = Lang.GetString("straat");
   this.LandLabel.Text = Lang.GetString("land");
} 

In plaats van in het bestand client.aspx alle tekst vast te coderen, maken we gebruik van Labels in de plaats. In de functie OnInit geven we alle labels een inhoud, afhankelijk van de gekozen taal. In dit voorbeeld werd de taal ingesteld door de gebruiken en wordt deze in een sessievariabele bewaard: Session["LANGUAGE"]. Het is tevens mogelijk om de kolomnamen van een DataGrid te veranderen vanuit de OnInit functie.

ASP

De mogelijkheden in ASP zijn een stuk beperkter. We kunnen niet via een codebehind file werken, er is geen ondersteuning voor objecten, etc… Daarom proberen we het geheel m.b.v. een functie af te handelen.

Function getString(strFieldName, language,strFile) 

Dim objDom 
Dim objRoot
Dim objField
Dim PageNo 

'XML file object
Set objDom = Server.CreateObject("Microsoft.XMLDOM")
objDom.async = False
strXMLFile = Server.MapPath(strFile)
objDom.Load (strXMLFile)

'Root XML Field
Set objRoot = objDom.documentElement

strFieldName = "//main/language[@id='" + language + "']/" + strFieldName);

'collect information from nodes 
Set objField = objRoot.selectSingleNode(strFieldName)

getString = objField.Text

'Release variables
Set objDom = Nothing
Set objRoot = Nothing
Set objField = Nothing

End Function 

Wanneer we een tekst wensen weer te geven in de gepaste taal gebruiken we volgende oproep:

<%= getString("fieldcode","languageid","filename")%>

Het nadeel van deze methode via ASP is dat u geen initiële waarden hebt voor uw tekstvelden. In een editor zoals Microsoft Visual Studio ziet u geen tekstvelden. Als u met labels werkt onder ASP.NET kunt u een initiële waarde geven aan een label. Dit mankement kan gedeeltelijk opgelost worden door <div> als label te gebruiken onder ASP.

Appendix

Voor de volledigheid van dit artikel wordt ook de code van de XmlLang class in VB.NET toegevoegd.

Imports System
Imports System.Xml

Public Class XmlLang
   Protected X As XmlDataDocument 
   Protected Lang As String

   Public Sub XmlLang(ByVal FileName As String, ByVal Language As String) 
      Dim Name As String 
      Name = "htp://localhost/myweb/xml/" & FileName 
      X = New XmlDataDocument()
      X.Load(Name)
      Lang = Language
   End Sub

   Public Sub XmlLang(ByVal FileName As String)
      Dim Name As String 
      Name = "htp://localhost/myweb/xml/" & FileName 
      X = New XmlDataDocument()
      X.Load(Name) 
      Lang = "N" 
   End Sub 

   Public Function GetString(ByVal Name As String) 
      Dim node As XmlNode 
      Dim result As String 
      node = X.SelectSingleNode("//main/language[@id='" & Lang & "']/" & Name)
      If node Is Nothing Then result = ""
      If Not node Is Nothing Then 
         Dim value As String
         value = node.InnerXml.ToString() 
         result = value 
      End If 

      GetString = result 
   End Function

End Class

copyright 2002 Tim Musschoot

<< vorige | ^ naar boven | overzicht | volgende >>
copyright 2000-2007 ASPNL