aSP实现多语言支持
纲 要 : 让 我 们 设 想 你 使 用 Active Server Pages 设 计 了 一 个 成 功 的 站 点 , 而 你 的 客 户 纷 纷 要 求 将 此 站 点 国 际 化 以 提 供 多 种 语 言 版 本 。这 时 候 你 该 怎 么 办?请 看 本 文。 正 文 : 一 、 介 绍 让 我 们 设 想 你 使 用 Active Server Pages 设 计 了 一 个 成 功 的 站 点 , 而 你 的 客 户 纷 纷 要 求 将 此 站 点 国 际 化 以 提 供 多 种 语 言 版 本 。 该 问 题 的 关 键 在 于 , 你 必 须 使 用 某 种 方 法 实 现 快 速 的 页 面 内 容 转 换 。 可 以 将 此 问 题 看 成 是 从 数 据 库 提 取 适 当 数 据 并 用 ASP 动 态 显 示 。 在 本 文 中 我 们 将 讨 论 如 何 使 用 Active Server Pages 的 字 典 对 象 以 及 一 个 后 台 数 据 库 实 现 国 际 化 支 持 。 具 体 实 现 过 程 分 以 下 三 个 步 骤 : ◇ 设 计 数 据 库 并 存 储 文 本 和 文 件 路 径 。 ◇ 从 数 据 库 读 取 数 据 到 字 典 对 象 。 ◇ 在 ASP 页 面 引 用 文 本 和 文 件 路 径 。 二 、 步 骤 1 - 设 计 数 据 库 并 存 储 文 本 和 文 件 路 径 我 们 需 要 在 数 据 库 设 计 上 花 些 时 间 。 使 用 此 数 据 库 , 我 们 希 望 能 够 把 所 有 要 用 到 的 文 本 和 图 片 适 当 编 目 , 并 且 这 些 文 本 和 图 片 不 能 重 复 ; 如 果 要 在 应 用 中 把 “ 是 ” 改 成 “ 确 定 ” , 希 望 只 在 一 个 地 方 作 改 动 ; Web 维 护 者 在 更 改 内 容 时 应 能 够 快 速 找 到 目 标 文 本 。 基 于 以 上 要 求 , 让 我 们 开 始 设 计 数 据 库 。 首 先 创 建 两 个 表 来 放 置 文 本 。 其 中 一 个 表 为 CommonStrings , 用 于 存 放 在 整 个 站 点 重 复 使 用 的 单 词 和 短 语 。 另 外 一 个 表 为 SpecializedStrings , 用 于 存 放 只 在 特 定 页 面 使 用 的 单 词 和 短 语 。 把 公 用 和 限 于 特 定 页 面 使 用 的 文 本 分 别 存 放 有 利 于 简 化 站 点 维 护 。 两 个 表 都 使 用 StringKey 字 段 来 标 记 纪 录 , 使 用 StringLanguage 来 说 明 所 用 语 言 , 联 合 StringKey 和 StringLanguage 创 建 一 个 主 键 。 字 段 StringHolder 用 来 保 存 单 词 、 短 语 或 语 句 。 这 个 字 段 必 须 创 建 唯 一 索 引 以 保 证 不 会 输 入 重 复 的 单 词 、 短 语 或 语 句 。 对 于 SpecializedStrings 表 , 还 需 要 一 个 额 外 的 字 段 ASPPage 来 标 记 文 本 所 在 的 ASP 页 面 。 对 于 图 片 文 件 , 我 们 可 以 使 用 相 同 的 步 骤 创 建 表 来 存 储 指 向 这 些 文 件 的 路 径 。 只 需 要 在 CommonImage 表 和 SpecializedImage 表 中 用 FileName 字 段 替 换 对 应 的 StringHolder 就 可 以 了 。 在 新 创 建 的 表 中 装 入 数 据 时 , StringKey 的 内 容 应 该 给 站 点 维 护 者 尽 可 能 多 的 提 示 以 表 明 页 面 上 将 显 示 的 文 本 。 例 如 , 对 于 一 个 在 线 销 售 站 点 来 说 有 关 拒 绝 承 诺 的 声 明 语 句 使 用 OrderDisclaimer 是 一 个 不 错 的 选 择 , 站 点 维 护 者 由 此 可 以 非 常 清 楚 地 了 解 使 用 该 记 录 将 在 Web 页 面 上 显 示 的 内 容 。 把 那 些 公 用 的 单 词 和 短 语 放 在 CommonStrings 表 。 这 样 , 维 护 者 就 知 道 如 果 他 们 修 改 CommonStrings 表 中 的 一 个 记 录 , 将 影 响 到 站 点 内 的 许 多 页 面 。 对 于 大 的 站 点 , 可 以 设 计 一 个 易 于 使 用 的 界 面 来 输 入 和 修 改 数 据 库 中 的 文 本 。 准 备 这 些 资 料 是 一 项 冗 长 乏 味 的 任 务 , 越 简 单 就 越 少 出 错 。 三 、 步 骤 2 - 从 数 据 库 读 取 数 据 到 字 典 对 象 字 典 对 象 ( Dictionary Object ) 是 一 个 多 用 途 的 服 务 器 端 对 象 , 它 相 当 于 二 维 数 组 , 保 存 了 键 以 及 与 键 相 关 联 的 数 据 。 提 取 数 据 的 唯 一 途 径 在 于 取 得 键 值 或 索 引 。 可 以 把 字 典 对 象 的 作 用 范 围 配 置 为 整 个 应 用 范 围 或 对 话 范 围 , 而 不 必 担 心 损 失 性 能 。 赋 予 应 用 层 作 用 范 围 意 味 着 对 象 只 被 实 例 化 一 次 , 且 所 有 会 话 均 使 用 同 一 个 字 典 对 象 。 以 下 代 码 创 建 两 个 字 典 对 象 实 例 , 分 别 和 两 个 文 本 表 关 联 。 记 住 , 我 们 希 望 对 象 只 被 初 始 化 一 次 , 所 以 把 这 些 代 码 放 在 Application_OnStart 事 件 中 : < Script RUNAT=SERVER Language=VBScript> Sub Application_OnStart() Dim DictCommonStrings Dim DictSpecializedStrings Dim Conn Dim rsCommonStrings Dim rsSpecializedStrings Set DictCommonStrings = Server.CreateObject("Scripting.Dictionary") Set DictSpecializedStrings = Server.CreateObject ("Scripting.Dictionary") 接 下 来 的 任 务 是 把 数 据 装 入 字 典 对 象 。 我 们 将 遍 历 表 , 连 接 StringKey 和 StringLanguage , 并 把 连 接 后 的 值 作 为 字 典 的 键 值 , 把 StringHolder 放 在 对 应 的 字 典 数 据 区 。 由 此 我 们 获 得 了 使 用 数 据 库 存 储 数 据 的 弹 性 , 并 避 免 了 持 久 的 数 据 库 连 接 而 导 致 的 性 能 影 响 。 事 实 上 , 数 据 库 只 在 应 用 启 动 时 被 访 问 一 次 , 其 后 ASP 页 面 将 从 速 度 更 快 的 字 典 对 象 读 取 所 需 数 据 。 '建立数据库连接 Set Conn = Server. CreateObject("ADODB.Connection")<BR> Conn.ConnectionString = "Some Connection String"<BR> Conn.open '打开 CommonStrings 表, 遍历所有记录并装入数据 Set rsCommonStrings = Conn.Execute("Select StringKey, StringHolder from CommonStrings") Do until rsCommonStrings.EOF DictCommonStrings.Add rsCommonStrings("StringLanguage") & rsCommonStrings("StringKey") _ ,rsCommonStrings("StringHolder") rsCommonStrings.MoveNext Loop '打开SpecializedStrings表, 遍历所有记录并装入数据 Set rsSpecializedStrings = Conn.Execute("Select StringKey, StringHolder from SpecializedStrings") Do until rsSpecializedStrings.EOF DictSpecializedStrings.Add rsSpecializedStrings ("StringLanguage") & _ rsSpecializedStrings ("StringKey") , rsSpecializedStrings ("StringHolder") rsSpecializedStrings.MoveNext Loop rsSpecializedStrings.Close rsCommonStrings.Close Conn.Close Set rsSpecializedStrings = Nothing Set rsCommonStrings = Nothing Set Conn = Nothing End Sub < /Script> 四 、 步 骤 3-在 ASP 页 面 引 用 文 本 和 文 件 路 径 接 下 来 的 工 作 是 在 ASP 页 面 引 用 已 经 实 例 化 的 字 典 对 象 中 的 文 本 ( 以 及 文 件 路 径 ) 。 首 先 我 们 需 要 知 道 当 前 用 户 所 使 用 的 语 言 , 其 中 一 个 办 法 是 从 Request.Server.Variables 取 得 该 值 。 请 把 下 列 代 码 放 入 Session_Onstart 事 件 处 理 过 程 : < Script Language=VBScript> Sub Session_OnStart() Session("Lang") = Request.Server.Variables("HTTP_ACCEPT_LANGUAGE") End Sub < /Script> 通 过 键 值 可 以 从 字 典 对 象 取 得 对 应 的 文 本 ( 或 图 片 文 件 路 径 ) , 键 值 由 语 言 前 缀 加 名 字 组 成 。 以 下 为 示 例 代 码 : < HTML> < P Align=center> < h1>< %= DictSpecializedStrings.Item(Session("Lang") & "Confirmation")%>< /h1> < /P><BR> < P Align=center> < h5>< %= DictSpecializedStrings.Item(Session("Lang") & "OrderDisclaimer")%>< /h5> < /P> < /HTML> 对 于 中 文 浏 览 器 , 该 页 面 的 提 示 类 如 : 感 谢 您 的 购 买 。 请 进 入 下 一 页 付 款 。 而 对 于 一 个 缺 省 语 言 为 英 文 的 的 浏 览 器 , 则 提 示 为 : Thank you for your order. Continue to the Next Page to make your payment. 根 据 我 的 经 验 , 从 字 典 对 象 引 用 文 本 ( 以 及 图 片 路 径 ) 和 直 接 在 ASP 代 码 中 输 入 数 据 相 比 , 没 有 性 能 上 的 不 利 影 响 。 这 是 由 于 文 本 ( 和 图 片 路 径 ) 字 典 被 放 在 内 存 中 , 因 而 可 以 快 速 地 提 取 。 五 、 讨 论 当 然 , 实 现 多 语 言 支 持 还 有 其 它 的 因 素 需 要 考 虑 。 使 站 点 内 容 的 变 化 和 应 用 开 发 者 隔 离 是 本 文 试 图 说 明 的 实 质 内 容 。 本 方 案 不 仅 对 于 实 现 站 点 内 容 国 际 化 非 常 有 用 , 而 且 对 于 站 点 内 容 频 繁 改 变 而 布 局 基 本 不 变 的 情 形 , 本 方 案 同 样 能 起 作 用 。 后 台 数 据 库 、 集 合 对 象 ( 字 典 对 象 ) 以 及 ASP 技 术 提 供 了 一 个 极 好 的 方 案 来 实 现 站 点 内 容 从 源 语 言 到 其 它 语 言 的 扩 展 。