Как общественность решает проблему многоязычности при генерации HTML страничек XSL? Скажем есть XML: <page> <header/> <menu/> <content> ... </content> </page>
И есть XSL, который, когда видит тэг <header/> генерирует заголовок. Hа конкретном языке. То есть помимо собственно выдачи HTML-тэгов он еще и текст выдает. Hе слишком удобно, если требуется сделать интерфейс одновременно для русского, английского и немецкого языков. Что делать? Вводить еще один уровень косвенности и вместо "Welcome, " писать <xsl:value-of select="$MsgWelcome">? (вообще-то я это еще не поверял, возможно это не лучшая или даже вовсе не рабочая идея).
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 вставлять языковые ресурсы в зависимости от текущего языка
> Как общественность решает проблему многоязычности при генерации HTML > страничек XSL? Скажем есть XML: > <page> > <header/> > <menu/> > <content> > ... > </content> > </page>
> И есть XSL, который, когда видит тэг <header/> генерирует заголовок. Hа > конкретном языке. То есть помимо собственно выдачи HTML-тэгов он еще и текст > выдает. Hе слишком удобно, если требуется сделать интерфейс одновременно для > русского, английского и немецкого языков. > Что делать? Вводить еще один уровень косвенности и вместо "Welcome, " писать > <xsl:value-of select="$MsgWelcome">? (вообще-то я это еще не поверял, возможно > это не лучшая или даже вовсе не рабочая идея).
У меня была такая задача. Из способов, которые я рассматривал можно привести следующие:
0. Во всех случаях языковые ресурсы хранятся в XML-файлах приблизительно следующего формата;
Это - общее для всей систем, испульзуется в апплетах/сервлетах/JSP/XSLT/whatever. Файлы поименованы как en.xml, de.xml и так далее в соответствии с ISO 3166. Документ выбирается примерно так:
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>
Я думаю, еще можно с десяток способов придумать. Я пользую первый, вотому как он хоть и неуклюжий но работает довольно шустрый и переносим.
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.
[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 (типичный ресурс :) ) вот такого вида:
AV> Я думаю, еще можно с десяток способов придумать. AV> Я пользую первый, вотому как он хоть и неуклюжий но работает довольно AV> шустрый и переносим. Wow, сколько от тебя сразу вариантов. ;-) Всем спасибо, теперь у меня есть над чем подумать и из чего выбрать.
[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. ... Мне бы ... Через камни струиться водой ледяной,/Господин мой Смерть.