Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Многоязычность XSL

14 views
Skip to first unread message

Konstantin Scheglov

unread,
Nov 27, 2001, 1:20:03 PM11/27/01
to
Hello everybody.

Как общественность решает проблему многоязычности при генерации HTML
страничек XSL? Скажем есть XML:
<page>
<header/>
<menu/>
<content>
...
</content>
</page>

И есть XSL, который, когда видит тэг <header/> генерирует заголовок. Hа
конкретном языке. То есть помимо собственно выдачи HTML-тэгов он еще и текст
выдает. Hе слишком удобно, если требуется сделать интерфейс одновременно для
русского, английского и немецкого языков.
Что делать? Вводить еще один уровень косвенности и вместо "Welcome, " писать
<xsl:value-of select="$MsgWelcome">? (вообще-то я это еще не поверял, возможно
это не лучшая или даже вовсе не рабочая идея).

--
С уважением, Konstantin.

Oleg Tkachenko

unread,
Nov 27, 2001, 3:51:10 PM11/27/01
to
Здравствуй Konstantin!

Tuesday November 27 2001 21:20, you wrote to All:

KS> И есть XSL, который, когда видит тэг <header/> генерирует заголовок.
KS> Hа конкретном языке. То есть помимо собственно выдачи HTML-тэгов он
KS> еще и текст выдает. Hе слишком удобно, если требуется сделать
KS> интерфейс одновременно для русского, английского и немецкого
KS> языков. Что делать? Вводить еще один уровень косвенности и вместо
KS> "Welcome, " писать <xsl:value-of select="$MsgWelcome">? (вообще-то я
KS> это еще не поверял, возможно это не лучшая или даже вовсе не рабочая
KS> идея).
Hа мой взгляд мультиязыковые ресурсы лучше организовывать в виде bundle, как в
java. Hехорошо, если xsl напрямую генерирует текст, он должен храниться
отдельно, в виде xml, в котором каждому ресурсу поставлен в соответствие язык,
тогда имея bundle.xml файл в виде, например
<header>
<text lang="ru">Русский заголовок</text>
<text lang="en">English header</text>
</header>

можно из xsl вставлять языковые ресурсы в зависимости от текущего языка

<xsl:template match="header">
<h3>
<xsl:value-of select="document('bundle.xml')//header/text[@lang=$lang]"/>
</h3>
</xsl:template>

Это, конечно, только один из вариантов.

Wbr, Oleg Tkachenko
ol...@multiconn.com
Multiconn International

Aleksei Valikov

unread,
Nov 28, 2001, 3:22:31 AM11/28/01
to
Hi.

У меня была такая задача. Из способов, которые я рассматривал можно привести
следующие:

0. Во всех случаях языковые ресурсы хранятся в XML-файлах приблизительно
следующего формата;

<resources xml:lang="de">
<resource name="recordTITLE">Titel</resource>
<resource name="recordABSTRACT">Kurzbeschreibung</resource>
<resource
name="recordACCESSCONSTRAINTS">Zugriffsbeschr├дnkungen</resource>
......
</resources>
<resources xml:lang="en">
<resource name="recordTITLE">Title</resource>
<resource name="recordABSTRACT">Abstract</resource>
<resource name="recordACCESSCONSTRAINTS">Access Constraints</resource>
......
</resources>
<resources xml:lang="fr">
<resource name="recordTITLE">Titre</resource>
<resource name="recordABSTRACT">R├йsum├й</resource>
<resource name="recordACCESSCONSTRAINTS">Contraintes d'acc├иs</resource>
.......
</resources>

Это - общее для всей систем, испульзуется в
апплетах/сервлетах/JSP/XSLT/whatever.
Файлы поименованы как en.xml, de.xml и так далее в соответствии с ISO 3166.
Документ выбирается примерно так:

<xsl:variable name="locale-given" select="$session/locale"/>
<xsl:variable name="locale">
<xsl:if test="not($locale-given)">en</xsl:if>
<xsl:if test="$locale-given"><xsl:value-of
select="$locale-given"/></xsl:if>
</xsl:variable>
<xsl:variable name="locale-filename" select="concat($locale,'.xml')"/>
<xsl:variable name="locale-document" select="document($locale-filename)"/>

Теперь варианты доступа:

1. Имена ресурсов уникальные, по ним можно строить ключи:
<xsl:key name="label" match="resources[lang($locale)]/resource"
use="@name"/>
И обращаться:
<xsl:for-each select="$locale-document">
<xsl:value-of select="key('label', 'gemetREMOVEITEM')"/>
</xsl:for-each>

Это самый эффективный способ (JServ/Oracle XSQL Servlet/Oracle XDK), но
писать громоздко. Когда в 2.0 сделают смену документа чтобы с key нормально
работало, будет лучший способ, типа:
<xsl:value-of select="key('label', 'gemetREMOVEITEM',$ld)"/>

2. Функция расширения:
<xsl:value-of select="lang:term('gemetREMOVEITEM')"/>
Модификация: экземаляр какого-нибудь наследника Dictionary, в него один раз
загружаются все ресурсы а затем
<xsl:value-of select="lang:term($res, 'gemetREMOVEITEM')"/>

3. Элемент расширения:
<lang:term name="gemetREMOVEITEM"/>

4. 2-step processing.
Первый шаг: выполняем преобразование, вместо текста, который требуется
перевести выводим
<term:gemetREMOVEITEM/>
Второй шаг:
<xsl:template match="term:*">
<xsl:variable name="name" select="local-name()"/>
<xsl:for-each select="$locale-document">
<xsl:value-of select="key('label', $name)"/>
</xsl:for-each>
</xsl:template>

Я думаю, еще можно с десяток способов придумать.
Я пользую первый, вотому как он хоть и неуклюжий но работает довольно
шустрый и переносим.

Bye.
/lexi

--
Отправлено через сервер Talk.Ru - http://www.talk.ru

Aleksei Valikov

unread,
Nov 28, 2001, 3:26:37 AM11/28/01
to
Hi.

> <xsl:value-of select="document('bundle.xml')//header/text[@lang=$lang]"/>

Лучше использовать функцию lang().
document('bundle.xml')//header/text[lang($lang)]

Oleg Tkachenko

unread,
Nov 28, 2001, 6:07:34 AM11/28/01
to
Aleksei Valikov wrote:


>><xsl:value-of select="document('bundle.xml')//header/text[@lang=$lang]"/>

> Лучше использовать функцию lang().
> document('bundle.xml')//header/text[lang($lang)]

Да, точно, это я просто забыл про нее, поскольку у нас в процессоре ее нетути. Тогда и атрибут должен быть xml:lang, а не просто lang.

--
Oleg Tkachenko
Multiconn International, Israel

Lev Serebryakov

unread,
Nov 28, 2001, 4:12:34 AM11/28/01
to
What do you think about sharp blades, Konstantin?

[Answer on] [Konstantin Scheglov wrote to All at [27 Nov 01 21:20]]:

KS> И есть XSL, который, когда видит тэг <header/> генерирует
KS> заголовок.
KS> Hа конкретном языке. То есть помимо собственно выдачи HTML-тэгов он
KS> еще и текст выдает. Hе слишком удобно, если требуется сделать
KS> интерфейс одновременно для русского, английского и немецкого
KS> языков. Что делать? Вводить еще один уровень косвенности и вместо
KS> "Welcome, " писать <xsl:value-of select="$MsgWelcome">? (вообще-то я
KS> это еще не поверял, возможно это не лучшая или даже вовсе не рабочая
KS> идея).
Я сделал файл strings.xml (типичный ресурс :) ) вот такого вида:

<?xml version="1.0" encoding="koi8-r"?>
<strings>
<lang id="en">
<string id="name">page name</string>
<string id="title">project's homepage</string>
<string id="version">version</string>
<string id="download">download</string>
<string id="stable">stable</string>
<string id="dev">development</string>
</lang>
<lang id="ru">
<string id="name">имя страницы</string>
<string id="title">домашняя страница проекта</string>
<string id="version">версия</string>
<string id="download">брать</string>
<string id="stable">стабильная</string>
<string id="dev">разрабатываемая</string>
</lang>
</strings>


В начале стиля гружу его в переменную STRINGS, а потом достаю из нее по мере
надобности:

<xsl:value-of select="$STRINGS/strings/lang[@id=$lang]/string[@id='title']"/>


Remember, pain is part of pleasure, Konstantin.
... Моя душа села в поезд за горизонт.

Konstantin Scheglov

unread,
Nov 28, 2001, 11:44:12 AM11/28/01
to
Hello Aleksei.

28 Nov 01 11:22, you wrote to me:

AV> Я думаю, еще можно с десяток способов придумать.
AV> Я пользую первый, вотому как он хоть и неуклюжий но работает довольно
AV> шустрый и переносим.
Wow, сколько от тебя сразу вариантов. ;-)
Всем спасибо, теперь у меня есть над чем подумать и из чего выбрать.

--
С уважением, Konstantin.

Lev Serebryakov

unread,
Nov 28, 2001, 1:24:06 PM11/28/01
to
What do you think about sharp blades, Aleksei?

[Answer on] [Aleksei Valikov wrote to Oleg Tkachenko at [28 Nov 01 11:26]]:

>> <xsl:value-of
>> select="document('bundle.xml')//header/text[@lang=$lang]"/>

AV> Лучше использовать функцию lang().
AV> document('bundle.xml')//header/text[lang($lang)]
lang() возвращает false, когда языка нет вообще, а иногда полезно отсутсвие
lang засчитывать за '*', скажем так. Правда, тогда и условия надо написать
посложнее.

Remember, pain is part of pleasure, Aleksei.
... Мне бы ... Через камни струиться водой ледяной,/Господин мой Смерть.

0 new messages