新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   >>中国XML论坛<<     W3CHINA.ORG讨论区     计算机科学论坛     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> 关于 XML 的一般性技术讨论,提供 XML入门资料 和 XML教程
    [返回] 中文XML论坛 - 专业的XML技术讨论区XML.ORG.CN讨论区 - XML技术『 XML基础 』 → 本地化和 XML/DHTML 菜单 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 7742 个阅读者浏览上一篇主题  刷新本主题   树形显示贴子 浏览下一篇主题
     * 贴子主题: 本地化和 XML/DHTML 菜单 举报  打印  推荐  IE收藏夹 
       本主题类别:     
     diy930 帅哥哟,离线,有人找我吗?双鱼座1979-3-8
      
      
      威望:4
      头衔:用脑专家
      等级:大三暑假(TOFEL考了650分!)
      文章:50
      积分:930
      门派:XML.ORG.CN
      注册:2004/7/12

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给diy930发送一个短消息 把diy930加入好友 查看diy930的个人资料 搜索diy930在『 XML基础 』的所有贴子 引用回复这个贴子 回复这个贴子 查看diy930的博客楼主
    发贴心情 本地化和 XML/DHTML 菜单

    编者按:以下文章仅用于示范,并没有反映某一 Microsoft 产品的任何开发过程。有关 XML 和 XSL 的详细信息,请访问新的 MSDN XML 开发者中心(英文)。

    请下载本文的示例代码(压缩文件,14.3K)

    “DXML”系列文章
    这是有关使用 XML 和 XSL 为 Web 站点开发动态 HTML (DHTML)用户界面的系列文章中的第四篇,也是最后一篇。在第一篇文章中,我们使用 XML 文件存储站点的目录 (TOC) 信息,使用 XSL、CSS 和脚本输出 DHTML TOC。在第二篇文章中,我们使用同一 XML 数据生成 DHTML 菜单,而在 microsoft.com 等 Web 站点中就用到了这些菜单。在第三篇文章中,我们讨论了在 Web 站点上实现 DHTML 菜单的三种特殊方式。

    如果要掌握这最后一篇文章中的大部分内容,需要您熟悉前面文章中提及的概念和代码。如果您还没有阅读前面的文章,我们建议您在阅读这一篇文章之前,先阅读前三篇。

    本地化
    本月,我们将实现 DHTML 菜单的日语和希伯来语版本。以这两种语言为例,我们将会看到将 XML 和 DHTML 针对非西欧字符集进行本地化要采用的一些有趣的方法,而且在希伯来语中,我们还将看到从右向左的(即,双向)的阅读顺序。

    这篇文章的目的是演示如何通过对我们的核心文件(menus.xml、menus.xsl、menus.jscript 和 menus.css)进行极小的改动(除了翻译 XML 文档中的内容之外),即能以浏览器所支持的任一语言发布 DHTML 菜单。

    以下是由 DHTML 实现的两个菜单的外观:



    图 1. 日语菜单



    图 2. 希伯来语菜单

    我们将提取 XML 文件的本地化版本,有两种编码形式:一种是特定语言的字符集编码,一种是 UTF-8 Unicode,并将提交这两种编码方式的 HTML 输出结果。我们将讨论动态和“脱机”生成 #include 文件所需的设置,并了解为了使我们的输出结果按所需方式实现,我们应告知浏览器的内容。

    这不是一篇讨论如何对代码进行本地化(这个主题相当耗人精力)的内容详尽的论文。与之相反,我们将了解与这一特定案例相关的基本概念,检查示例代码,并在进行过程中为您指出查阅详细内容的位置。我们将多次引用可供下载的示例代码,所以在继续之前,您可能会下载示例代码。请参阅压缩文件中的 README.txt 文件,以获取指导信息。

    Unicode 字符集与特定语言的字符集的比较
    显示文字的方式有两种:一种是特定语言的字符集,一种是 Unicode。Unicode 有很多优点:每一个独立的字符集在字符集中有自己的“空间”,所以支持 Unicode 的查看程序能够同时查看多种语言。正是因为同一原因,Unicode 允许您在无需指定字符集的情况下对一种语言进行处理。然而,因为对许多应用程序来说 Unicode 支持功能相对较新,所以指定特定语言的字符集仍很普遍。因为 Internet Explorer 4.0 和 Internet Explorer 5 都支持 Unicode — 所以如果这两种是您的目标浏览器设置,我们强烈建议您采用 Unicode。

    如果要快速了解 Unicode,请参阅 Web Workshop 中的 Unicode(英文) 以及在 Microsoft 全球软件开发站点上阅读 Unicode、字符集和代码页(英文) 详细内容,请参阅 Microsoft Typography 站点上的 字符集(英文)。

    在 XML 文档中进行本地化
    除了翻译内容之外,对于我们在这一系列文章中使用的英语 XML 数据,我们只需要进行两处改动。第一处是指定文档的编码方式。对于希伯来语菜单,如果以特定语言的字符集(即 windows-1255)编写 XML,XML 处理指令如下所示:

    <?xml version="1.0" encoding="windows-1255"?>

    对于以 Unicode UTF-8 编码的 XML,处理指令如下所示:

    <?xml version="1.0" encoding="UTF-8"?>

    因为 Internet Explorer 5 支持这两种字符集,在浏览器中查看时,这些“未经处理”的 XML 文件的外观效果是一样的:

    (如果您的浏览器不支持inline frames,请点击这里在单独的页面观看此图)

    图 3. 在 Internet Explorer 5 中查看的 windows-1255 编码的希伯来文 XML 文件

    (如果您的浏览器不支持inline frames,请点击这里在单独的页面观看此图)

    图 4. 在 Internet Explorer 5 中查看的 UTF-8 编码的希伯来文 XML 文件

    Internet Explorer(以及 XML 分析程序)所支持的所有字符集和代码页的列表,请参阅 Web Workshop 中的字符集识别(英文)。

    对我们文件的第二处修改是在 XML 中指定 DIR 节点内容的阅读顺序。在希伯来语(以及阿拉伯语)中,阅读顺序是从右到左。在日语中,阅读顺序是从左到右。在 XSL 中我们会利用这一点告知浏览器提交内容的顺序。

    在 XML 自身中只需要进行这些改动。我们将一点一点地查看对 XSL 和脚本进行的改动。首先,我们看一看需要在服务器上进行的操作。

    在 Web 服务器上进行的本地化
    通过 Windows 在 Web 服务器处理本地化的文字非常简单直观。在客户机中,如果您对 XML 进行 ASP 处理,您只需要保证在操作系统上安装了相应的语言包。(如果您只是向下发送已本地化的 HTML 或 XML,而不进行 ASP 处理,则不需要语言包)。如果您需要使用英语版本,则系统中已安装了西欧语言支持功能。至于日语和希伯来语等其他语言包,则可以下载。如果您在服务器上运行的是 Internet Explorer 5(无论什么情况,我们都强烈建议您使用这一浏览器),则浏览器自身即可进行语言包的升级工作,方法是:转到“工具”、“Windows 更新”,选择所需语言包。

    Internet Explorer 4.0 同样支持通过“Windows 更新”添加语言包,但所支持的语种没有版本 5 多。例如,一篇希伯来语文档,可能能够在安装了 Internet Explorer 5 的任一台 Windows 机器上运行,但包括 Internet Explorer 4.0 在内的其他浏览器就需要相应语言版本的 Windows。

    使用非默认字符集的任何 Active Server Pages (ASP) 文件都需要使用 @CODEPAGE 命令在页首指明这一信息。这一命令必须包含在 ASP 页的首行内;多个命令也必须位于同一行内。在下面的例子中,我们指定日语代码页以及该页默认的脚本语言。

    <% @ CODEPAGE="932" LANGUAGE="JScript" %>

    运行以 Unicode UTF-8 编码的日语(或任一语言)需要以下代码页。

    <% @ CODEPAGE="65001" LANGUAGE="JScript" %>

    每一篇文档(包括所有的 #includes)只能指定一个代码页。

    在服务器上动态转换 XML
    因为页中所有的 include 文件都继承宿主文档的代码页,我们指定了代码页后,include 能够自行进行设置。针对我们为动态 include 所举的示例(示例代码中的示例 3 和 8),我们只需照常进行 transformNode()。我将 XML 文件作为参数传递给 include, 而后者只需要指定 Request.QueryString 即可。

    <%
      // MENUS_DYN.INC

      var sXml = String(Request.QueryString("xml"));
      var sXsl = "menus.xsl";
      
      var oXmlDoc = Server.CreateObject("Microsoft.XMLDOM");
      oXmlDoc.async = false;
      oXmlDoc.load(Server.MapPath(sXml));
      
      if (0 != oXmlDoc.parseError.errorCode)
      {
        Response.Write('XML parseError on line ' + oXmlDoc.parseError.line);
        Response.End();
      }

      var oXslDoc = Server.CreateObject("Microsoft.XMLDOM");
      oXslDoc.async = false;
      oXslDoc.load(Server.MapPath(sXsl));

      if (0 != oXslDoc.parseError.errorCode)
      {
        Response.Write('XSL parseError on line ' + oXslDoc.parseError.line);
        Response.End();
      }

      Response.Write(oXmlDoc.transformNode(oXslDoc));
    %>

    无论我们使用的是 UTF-8 代码页还是特定语言的代码页,动态 include 都能够自行设置。

    脱机创建静态 Include
    就像在上一篇文章中讨论的那样,可能会存在一些正当理由(如服务器负荷),使得我们不希望在运行时将 XML 动态转换到 HTML,而是脱机创建 includes,在运行时调用预先创建的 HTML(我们已演示了如何使用 Scripting.FileSystemObject 进行这一操作)。在处理本地化的 XML 时可以采用同一种方式,但有一点特别重要,您必须使用特定语言的字符集。请参阅示例代码中的示例 4。

    XML 内部即可处理 Unicode,默认情况下在转换过程中将传递 Unicode 编码。在进行动态转换时,因为将从宿主文档的 CODEPAGE 命令中获取编码线索,所以这还不是什么问题。但是,脱机情况下转换到一份独立的文件时,就没有这样的线索了。必须告知分析程序我们将使用代码页,而不是 Unicode 或系统默认设置。我们所采取的措施是:加载一个“哑”对象,在要求的编码中带有一篇 XML 文档,将其 documentElement 替换为我们已转换的对象。最后,因 FileSystemObject 使用系统的语言设置,我们需要使用 XMLDocument.save() 方法保存静态文件。这种方式做起来没有听起来那么复杂。

    <% @ LANGUAGE="JScript" %>
    <%
      // MAKEMENU.ASP

      var sLang = String(Request.QueryString("lang"));
      if ("undefined" == sLang)
      {
        Response.Write('请指定一种语言。 ');
        Response.End();
      }

      var sXml = "menus_" + sLang + ".xml";
      var sXsl = "menus.xsl";
      
      var oXmlDoc = Server.CreateObject("Microsoft.XMLDOM");
      oXmlDoc.async = false;
      oXmlDoc.load(Server.MapPath(sXml));
      
      if (0 != oXmlDoc.parseError.errorCode)
      {
        Response.Write('XML parseError on line ' + oXmlDoc.parseError.line);
        Response.End();
      }

      var oXslDoc = Server.CreateObject("Microsoft.XMLDOM");
      oXslDoc.async = false;
      oXslDoc.load(Server.MapPath(sXsl));

      if (0 != oXslDoc.parseError.errorCode)
      {
        Response.Write('XSL parseError on line ' + oXslDoc.parseError.line);
        Response.End();
      }

      //技巧,确保将需要的编码传递到输出 XML
      //加载带有适当编码的菜单 xml 文件的 XML 对象
      //然后用实际转换的 XML 的文档元素来替换其 documentElement

      var oOutput = Server.CreateObject("Microsoft.XMLDOM");
      oOutput.load(Server.MapPath(sXml));
      var oTempOutput = Server.CreateObject("Microsoft.XMLDOM");
      oXmlDoc.transformNodeToObject(oXslDoc,oTempOutput);
      oOutput.documentElement = oTempOutput.documentElement;
      
      var sIncFileName = "menus_stat_" + sLang + ".inc";
      oOutput.save(Server.MapPath(sIncFileName));
    %>

    我将双字节语言代码作为参数传递给页,这一参数将成为 sLang 变量,因此,这一 ASP 页能够使用任一种编码方式预先生成 include 文件。注意我们使用了 oTemp,它只是用于保存已转换的 XML,并将其 documentElement 传递到 oOutput,而其中已“填充”了带有适宜编码方式的 menus-xx.xml 文件。因为我们是保存到文件,所以需要再次进行这一操作;这种情况下 CODEPAGE 命令不能为我们提供帮助。

    如果只使用 Unicode 进行输出,则不需要添加这一过程。请参阅示例代码的示例 9。

    如果您根本没有改动服务器上的 XML(例如,只是直接将 XML 发送给客户机),则不需要在 ASP 文件中指定代码页。

    在 Web 浏览器中进行本地化
    与在服务器上一样,在客户机上处理本地化的 XML 和 HTML 也需要安装相应的语言包。除此之外,对于客户机端代码还必须进行一些改动:增加 META 内容类型标记,用于指定浏览器提交内容的字符;对所有本地化元素设置 DIR 属性(只有 BiDi 语言有此要求);对于从右向左的语言,还要增加一些 JScript,将菜单右对齐。

    META 内容类型
    为了使 Internet Explorer 正确地提交内容,需要在文档的 HEAD 部分设置 META 标记。这将指定 HTML 的内容类型。如下所示,我们为希伯来语 windows-1255 和 UTF-8 HTML 文件指定了 META 标记。

    <HTML>
    <HEAD>
      <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1255">

    <HTML>
    <HEAD>
      <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">

    这些字符集与 XML 文件中所用的字符集严格对应,简化了操作。

    DIR 属性
    查看希伯来语菜单的屏幕图片(图 2),您会发现菜单的显示是从右向左,而“常规文档内容” 的显示是从左向右。我们在元素的 DIR 属性中指定“RTL”(从右向左),即能以这种阅读顺序提交该元素。既可对单个元素设置 DIR,也可对 HTML(顶级)元素或以上两者的组合设置 DIR。

    以下是希伯来语菜单的菜单栏 <DIV> 元素开始处的 HTML。

    <DIV ID="divMenuBar" DIR="RTL"
      ONMOUSEOVER="if (document.all) MenuBar_over();"
      ONMOUSEOUT="if (document.all) MenuBar_out();"
      ONSELECTSTART="return false;" >

    如前所述,我们将这些阅读顺序信息存储在 XML 文档的顶部,并通过 XSL 样式表传递给 HTML 输出。请您快速浏览一下上面图 3 或图 4 中的第四行。以下是实现这种效果的代码。

    <xsl:attribute name="DIR"><xsl:value-of select="/TOPICLIST/DIR" /></xsl:attribute>

    我们只需要在 XSL 中将这一行添加到需要输出阅读顺序敏感型元素的位置,这些元素就能够获取在浏览器中正确显示所需的信息。

    在脚本中进行菜单定位
    尽管 DIR 属性能够较好地处理元素中文字的阅读顺序,它却无法在需要时自动使菜单对菜单栏进行右对齐。就像我们必须在脚本中对英文菜单的元素进行显式定位一样,对于从右向左的编码,我们也需要进行这一操作。比较方便的是,我们可以检查 DIR 属性值,然后只需要添加一行 JScript 条件语句,即可完成这一操作。

    以下是对 menus.js 脚本文件中的 OpenMenu() 函数进行修改后的代码。

    eMenu.style.left = eSrc.parentElement.offsetLeft + divMenuBar.offsetLeft;
    if ("RTL" == eMenu.getAttribute("dir").toUpperCase())
    {
      eMenu.style.left = eMenu.offsetLeft - eMenu.offsetWidth + eSrc.parentElement.offsetWidth;
    }

    如果元素的 DIR 属性表明其阅读顺序是从右向左,我们可以通过减去菜单的宽度,再加上表单元格的宽度,对菜单的位置进行调整。由此可以将菜单的右边缘与菜单栏中相关项目的右边缘对齐。

    如果不希望在菜单中出现文字折行,则不应该像这种情况一样,在 .css 文件中固定菜单的宽度,而是应该作为菜单中最长字符串长度的一个函数,在 OpenMenu() 中进行动态设置(以百分比方式或“em”单位的形式)。我将 这作为一个练习留给读者。

    另一处修改
    我对 XSL 文件还进行了一项修改,在原来的代码中,我们使用 TOPICLIST 的 TYPE 属性设置用于脚本的表单元格输出的 ID 号。因为这有可能受到字符集的影响,我对代码进行了修改,使用 XSL uniqueID() 方法。这种方法将分配一个独一无二的数字 ID 号,在浏览器中实时运行脚本时能够避免受到字符集的任何干扰。我将原来的代码作为注释保留在 menus.xsl 格式表中。

    <xsl:attribute name="ID">tdMenuBarItem<xsl:eval>uniqueID(this)</xsl:eval></xsl:attribute>

    总结和其他信息
    使用 XML 保存并转换本地化的项目易于反掌。我们只需要在 XML 文件中添加一类属性和一个元素,在 XSL 文件中添加一行,再在脚本文件中添加一行,我们就能够处理浏览器所支持的任一种语言。

    因为 Internet Explorer 5 中对语言支持功能进行了加强,它肯定是理想的目标浏览器。如果您的目标受众使用的正是这种浏览器,您就可以谢天谢地,直接使用 Unicode UTF-8 作为编码方式,从而不需要再操心与特定语言相关的代码页,并可获得基于浏览器的最广泛的语言支持功能。对于您来说,它也是一个非常不错的开发环境。


       收藏   分享  
    顶(0)
      




    ----------------------------------------------
    我只知道,用 xml 做网站,可以省我很多时间.

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2004/7/21 13:43:00
     
     GoogleAdSense双鱼座1979-3-8
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 XML基础 』的所有贴子 访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2024/9/27 13:15:26

    本主题贴数1,分页: [1]

    管理选项修改tag | 锁定 | 解锁 | 提升 | 删除 | 移动 | 固顶 | 总固顶 | 奖励 | 惩罚 | 发布公告
    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    78.125ms