From: http://xmlhack.ru/faq/
Subject: Русский XML FAQ
Русский XML FAQ
Оригинал находится по адресу: http://xmlhack.ru/faq/
- О русском XML FAQ
- Группировка в XSLT
- Xerces, Xalan, FOP, русские буквы
- MSXML
- Java: Русские буквы и не только...
- Циклы в XSLT
- Повторное использование тега при XSLT трансформации
- Изменить значение переменной XSLT
- www.citforum.ru об XSLT
- PHP и XML
- <meta> с кодировкой в выводе XSLT
- Форматирование текста в XSLT
- Элементы или атрибуты?
О русском XML FAQ
Русский XML FAQ создаётся силами добровольцев. Каждый может добавить
пару вопрос-ответ в faq или дополнить существующий ответ. FAQ
постоянно пополняется и изменяется, самая последняя версия доступна по
адресу http://xmlhack.ru/faq/ или в виде одного файла -
http://xmlhack.ru/faq/ruxmlfaq-devel.html
FAQ распространяется по лицензии public domain. Вы можете использовать
его где угодно и как угодно.
Текстовая версия FAQ делается примерно так:
lynx --dump 'http://xmlhack.ru/faq/faq?_recurse=1&file=1&render=simple
Группировка в XSLT
От: Nikolai Grigoriev (grig@iitp.ru)
Тема: Re: Можно ли вот такое сделать в XSLT:
Группа: fido7.ru.xml
2. key('YMD', XYZ) - набор всех news, имеющих
значение даты XYZ (node-set);
3. generate-id() применительно к node-set дает id первого узла.
Поэтому фильтр в скобках первого for-each пропускает только
самые первые элементы для каждого значения даты - то есть,
создает набор уникальных значений (имхо, самое сложное
место во всей схеме).
Настройка FOP на русский язык описана на сайте Russian FOP:
http://www.openmechanics.org/rusfop/ (автор -- Алексей (aka Achtung) V. Алишевских).
> > А может стоит добавить в трактат про русские буквы раздел об XML? В
> > частности про борьбу с Xerces, Xalan, FOP. Вопросы про них здесь в
> > последнее время весьма часто появляются.
> > Может кто-то из тех, кто уже сталкивался с этой проблемой напишет
> > кусочек про ЭТО для экономии времени... :)
Предлагаю описание решения проблемы русификации FOP:
1. Пропатчить Xerces:
- Выкачать исходники Xerces
- В файл Encodings.java добавить строчки:
new EncodingInfo( "Cp1251", "Cp1251", 0xFF ),
new EncodingInfo( "Windows-1251", "Cp1251", 0xFF ),.
- Откомпилировать Хerces (набрать команду build.bat или build.sh - в
зависимости от операционной системы)
- Получившийся в результате компилляции файл xerces.jar (в каталоге build)
скопировать в каталог lib у FOP
- FOP (0.20.1).
2. В файле FO (или XML и XSL) написать в заголовке:
<?xml version="1.0" encoding="WINDOWS-1251"?>
Теперь можно писать в этом файле по русски в кодировке Cp1251 или
UNICODE
3. В соответствующий каталог (в данном случае c:fop-0.20.1conffonts)
скопировать файлы ttf из системного каталога Windows. Для Arial
normal/normal, normal/bold, italic/normal и italic/bold нужны файлы
arial.ttf, arialbd.ttf, ariali.ttf и arialbi.ttf.
4. Сгенерировать файлы описаний шрифтов (типа arial.xml).
Для этого для каждого шрифта нужно выполнить команду:
java -cp
.;c:fop-0.20.1buildfop.jar;c:fop-0.20.1libbatik.jar;c:fop-0.20.1lib
xalan-2.0.0.jar;c:fop-0.20.1libxerces.jar;c:fop-0.20.1libjimi-1.0.jar
org.apache.fop.fonts.apps.TTFReader fontsarial.ttf fontsarial.xml (это
для Arial normal/normal)
5. В FOP добавить в conf/userconfig.xml описание шрифта с русскими буквами,
типа:
<font metrics-file="c:fop-0.20.1conffontsarial.xml" kerning="yes"
embed-file="c:fop-0.20.1conffontsarial.ttf">
<font-triplet name="Arial" style="normal" weight="normal"/>
<font-triplet name="ArialMT" style="normal" weight="normal"/>
</font> .
Аналогично добавляются Arial normal/bold, italic/normal и italic/bold.
6. При вызове FOP из командной строки после org.apache.fop.apps.Fop
писать -c c:fop-0.20.1confuserconfig.xml
Если нужно использовать FOP из сервлета, то нужно в сервлете после строчки
Driver driver = new Driver();
добавить строчки:
String userConfig = "fonts/userconfig.xml"; //Каталог fonts
(c:weblogicfonts) был создан исключительно для удобства.
File userConfigFile = new File(userConfig);
Options options = new Options(userConfigFile);
Тогда расположение файлов ttf в файле userconfig.xml можно указать
относительно корня сервера приложения, без указания абсолютного пути:
<font metrics-file="fonts/arial.xml" kerning="yes"
embed-file="fonts/arial.ttf">
<font-triplet name="Arial" style="normal" weight="normal"/>
<font-triplet name="ArialMT" style="normal" weight="normal"/>
</font>
7. В файле FO (или XML и XSL) перед использованием шрифта писать:
font-family="Arial"
font-weight="bold" (Если используется Arial bold)
font-style="italic" (Если используется Arial italic)
8. Скомпиллированный файл xerces.jar указать в путях сервера приложений
(если нужно использовать FOP из сервлета).
PS. Таким способом мною были добавлены шрифты Arial и Times. Этого вполне
хватает для генерации отчетов.
Замечание к п.1:
если в Encodings.java последний параметр конструктора сделать не 0xFF,
а 0xFFFF,
new EncodingInfo("Cp1251", "Cp1251", 0xFFFF)
то xerces будет выводить XML-документы в данной кодировке без
преобразования русских букв в последовательности вида &#xxxx; Этот
совет касается по крайней мере некоторых старых версий xerces, 1.2.x,
на более новых не проверялся, хотя структура Encodings.java не
изменилась, т.е. все должно работать по-старому.
суть проблемы: даже после ковыряния в исходниках
xerces'а xalan ругался на кодировку.
всё пофиксилось после прочтения соответствующей
приписки.
Лежит эта приписка в исходниках xalan:
[ xalan-jsrcorgapachexalanxpathdtmpackage.html ]
вкратце, мысль следующая:
чтобы xalan использовал пропатченный xerces,
нужно при создании XSLTProcessor'а использовать
синтаксис:
org.apache.xalan.xslt.XSLTProcessor xsltProc =
org.apache.xalan.xslt.XSLTProcessorFactory.getProcessor(
new org.apache.xalan.xpath.xdom.XercesLiaison());
другой вариант исправления был найден, когда
я заставил ant'а собирать xalan-j:
в файле
[ orgapachexalanxpathxmlFormatterToXML.java ]
после строки:
s_revsize.put("KOI8-R", new Character('uFFFF'));
добавляются:
s_revsize.put("CP1251", new Character('uFFFF'));
s_revsize.put("CP866", new Character('uFFFF'));
После чего можно использовать .getProcessor() и не заморачиваться.
От: "Igor S. Mikhailov" <igor@alter.ru>
Тема: Re: xslutput
Группа: fido7.ru.java
> > Результат есть но в виде:
> > Назва
> > Где грабли?
> Если Xerces/Xalan то <<http://xmlhack.ru/faq/cache/4.html>>.
Для jdk1.4 разобрать src.zip, добавить как написано в статье выше
new EncodingInfo("Cp1251", "Cp1251", 0xFFFF),
new EncodingInfo("Windows-1251", "Cp1251", 0xFFFF)
в orgapachexalanserializeEncodings.java ,
откомпилять и положить новый Encodings.class в rt.jar. Все.
Объясняю по шагам последовательность для JDK 1.4.x:
1. Создаёшь каталог %JAVA_HOME%jrelibendorsed
2. Копируешь туда
<http://people.comita.spb.ru/users/sergeya/java/XalanRusChars.jar>
3. Наслаждаешься результатом
:-)
...
MSXML
> У меня не работают (или неправильно работают) XSLT-преобразования. >
Использую MSXML. В чем дело?
Скорее всего используется старая версия MSXML. Типичные симптомы: -
при попытке выполнить корректные преобразования, определенные в
пространстве имен с URI "<http://www.w3.org/1999/XSL/Transform">
не происходит ничего или выдается ошибка; - при попытке выполнить те
же преобразования, исправив URI на
http://www.w3.org/TR/WD-xsl , процессор пытается выполнить
преобразование, но выдает ошибку, о некорректности преобразование (в
то время, как оно работает на других процессорах); - в преобразованиях
не работают переменные, именованные шаблоны, шаблоны значений
атрибутов, ключи и импортирование.
Если наблюдается что-либо похожее, значит используется старая версия
MSXML. Пространство имен TR/WD-xsl соответствует раннему драфту XSLT,
который не совместим со стандартом языка XSLT, но до сих пор широко
используется Microsoft. Чтобы пользоваться "нормальным" XSLT в MSXML,
надо обновить версию:
MSXML3
http://msdn.microsoft.com/downloads/default.asp?URL=/downloads/sample.asp?url=/msdn-files/027/001/596/msdncompositedoc.xml
MSXML4
http://www.msdn.microsoft.com/code/default.asp?url=/code/sample.asp?url=/msdn-files/027/001/469/msdncompositedoc.xml
> Я поставил новую версию MSXML но все равно ничего не работает!
Как было сказано выше, старая версия языка широко используется в
решениях Microsoft, поэтому в новых версиях MSXML он WD-xsl не
отказались. По умолчанию MSXML ставится в так называемом side-by-side
mode, при котором апдейт XSLT не касается, к примеру, MSIE. Чтобы
использовать нормальный XSLT нужно ставить в replace-mode. Вот
маленькая утилика, которая все делает как надо:
http://www.msdn.microsoft.com/code/default.asp?url=/code/sample.asp?url=/msdn-files/027/001/469/msdncompositedoc.xml
Также см. http://www.netcrucible.com/xslt/msxml-faq.htm
По этому поводу очень подробно есть в FAQ ru.java - <http://www.javapower.ru>
А если конкретнее, то на странице С. Астахова -
<http://people.comita.spb.ru/users/sergeya/java/ruschars.html>
Циклы в XSLT
> Что-то никак в голову не приходит идея, как организовать цикл:
> 1. хотелось бы, чтобы результат поиска возвращал текущую страницу в рекордсет
е
> в XML, не нужно передавать на клиента 15000 записей :-)
> 2. хотелось бы, чтобы XSLT, в зависимости от номера страницы, рисовал
> навигатор
> с тем десятом страниц, куда текущая входит.
>
> то есть, имеем текущую страницу 26, навигатор должен нарисовать ссылки на
> 21 22 23 24 25 26 27 28 29 30
>
> ничего стройного в голову не лезет
<xsl:call-template name="for">
<xsl:with-param name="i" select="$number - ($number mod 10) +1"/>
<xsl:with-param name="n" select="$number - ($number mod 10) +11"/>
</xsl:call-template>
где $number содержит номер твоей страницы.
Есть еще один способ создания циклов.
Можно использовать документ вида:
<root>
<i n="0"/>
<i n="1"/>
......
<i n="xxxxx"/>
</root>
подгрузить этот документ в переменную:
<xsl:variable name="enumDoc" select="document('enum.xml')"/>
и гонять по нему цикл:
<xsl:for-each select="$enumDoc/enum/i[@d >= 1 and @d <= xxxxx]">
Относительно первого случая можно не беспокоиться за переполнение стека,
но зато получается немного более громоздко, да и надо заранее предвидеть
максимальное число циклов.
Я использовал как раз такой способ для нуумерации страниц (максимум 65535)
используя два вложенных цикла по 256 строк в каждом.
ЗЫ. Тут еще один подводный пень есть. Надо переменную оригинального документа
сохранить для использования внутри цикла.
В предыдущем примере неточность, надо /enum/ заменить на /root/
Sorry.
Повторное использование тега при XSLT трансформации
>>Есть хмл
>> <root>
>> <client>Maxim</client>
>> </root>
>> надо сделать из него Квитанцию и Уведомление.
>Я бы сделал так
>
><xsl:template match="root">
> <xsl:for-each select="client">
> <xsl:call-template name="kvit"/>
> <xsl:call-template name="uved"/>
> </xsl:for-each>
></xsl:template>
>
><xsl:template name="uved">
> <xsl:text>Уведомление-</xsl:text><xsl:value-of select="."/>
></xsl:temlpate>
>
><xsl:template name="kvit">
> <xsl:text>Квитанция-</xsl:text><xsl:value-of select="."/>
></xsl:temlpate>
>
>Обрати внимание, что есть <xsl:template match="..."> и
><xsl:template name="...">
Alexander A. Golev wrote:
>
> Что-то как объявить переменную я понял, а как у нее значение изменить,
> чтобы не ругалось на повторное объявление?
>
Никак. Это тебе не С, учись программировать без присваиваний.
Переменные XSLT обсуждались в треде "Идеологический вопрос", ближе к
концу:
<http://groups.google.com/groups?hl=ru&th=be43a163027897ff&seekm=9
98371731%40p69.f1609.n5020.z2.ftn#link1>
www.citforum.ru об XSLT
Q: Я прочитал статью на
<http://www.citforum.ru/internet/xml/part3.shtml> и попробовал
сделать так, как там написано. Почему у меня ничего не работает?
A: Потому что там описана настолько дремучая и устаревшая версия
"якобы" XSLT, которая не соответствует никакому стандарту, и никем не
поддерживается. Читайте нормальную документацию на w3c.org, ставьте MS
XML не ниже 3.0 (с MSIE 6.0 уже стоит), и делайте как написано в Help
от MS XML.
PHP и XML
Часть русского PHP FAQ от phpclub'а (<http://faq.phpclub.net/>)
содержит сведения про PHP XML --
<http://faq.phpclub.net/index.php3?theme=1&level=3&chapitre_id_sel
ect=41&document_id_select=2>.
xmlfaqATxmlhackDOTru
Форум PHPClub "PHP + XML + XSLT + XSL":
<http://phpclub.net/talk/forumdisplay.php?forumid=16>.
<meta> с кодировкой в выводе XSLT
От: Oleg Tkachenko (Oleg.Tkachenko@p5.f506.n400.z2.fidonet.org)
Тема: хочу заюзать новый xalan с jdk1.4
Группа: fido7.ru.java
Здравствуй Igor!
Tuesday April 02 2002 11:55, you wrote to All:
IM> jdk? И как избавиться от <meta> с кодировкой в выводе (<xslutput
IM> method="html" encoding="windows-1251"/> - все прописано)?
xslt процессоры обязаны его генерировать в HTML режиме вывода и если есть
элемент head - отсюда все твои варианты: либо выводить в режиме xml, либо без
head, либо постпроцесс какой-нибудь. А чем она мешает-то?
Wbr, Oleg Tkachenko
olegt@multiconn.com
Multiconn International
saxon умеет отключать мету:
=== Cut ===
The saxonmit-meta-tag attribute
This attribute may be set on the xslutput element when
method="html". The normal action of the HTML output method, as
specified in the XSLT standard, is to generate a <META> tag
immediately after the <HEAD> tag, containing details of the media type
and character encoding. Setting this attribute to "yes" causes this
output to be suppressed. Typical usage is
<xslutput method="html" saxonmit-meta-tag="yes">
=== Cut ===
Форматирование текста в XSLT
От: Aleksei Valikov (valikov@fzi.de)
Тема: Re: пачка вопросов
Группа: fido7.ru.xml
Число: 2002-04-18 12:08:27 PST
> Потребовалось тут немного xml/xsl вспомнить, а точнее изучить новые
> возможности современного XML. Задачка класическая: написать xsl для
> конвертирования xml-ля в text,html,rtf,pdf
> Ну с html более менее понятно, а вот для text и rtf вопросы возникли
> (sorry если вдруг что то из faq проскочило)
>
> PLAIN TEXT форматирование:
>
> - как обозначить перевод строки ?


...
> - как ограничить длину всех строк в тексте "максимум 80 символов" ?
Ох непросто. Не тем концом отвертки гвозди забиваете.
Можно написать рекурсивный шаблон, которому передаются два параметра:
текущая длина строки и остаток строки. Шаблон берет первый токен остатка
строки, отделенный пробелами, складывает его длину с текущей длиной строки
плюс один и сравнивает с 80. Если больше, то выводит 
, и вызывает сам
себя с текущей длиной строки равной 0 и тем же остатком строки. Если меньше,
то выводит пробел, затем первый токен остатка строки и вызывает себя с новой
текущей длиной строки равной старой текущей длине строки плюс длина первого
токена текущего остатка строки плюс единица и с новым остатком строки равным
части старого текущего остатка после пробела после первого токена старого
текущего остатка строки.
Однако, как очевидно из вышесказанного, это есть извращение. Легче написать
либо расширение либо простенький фильтр.
XSLT слабо подходит для форматирования текста.
> - как сделать, чтобы первые буквы стали заглавными ?
Тоже непросто. Описывать рекурсивную функцию и как ее писать я не буду,
<бессовестная-самореклама>посмотри в моей книжке по XSLT, там про рекурсии
есть</бесовестная самореклама>. Строчные/прописные буквы можно друг на друга
заменять при помощи функции translate, <бессовестная-самореклама>опять же
пример функции в книжке есть</бесовестная самореклама>.
Но, честное слово, подыщи для форматирования текста другой инструмент. XSLT
работает со структурой документа.
...
> HTML форматирование:
>
> - как обозначить пробел не самим пробелом, а   например ?
> (сам по себе конечно же не проходит)
Пиши  . Это неразрываемый пробел в Unicode. Большинство нормальных
процессоров при методе html выводят его как .
Элементы или атрибуты?
Выбор между элементом или атрибутом.
<note date="xxx"> ... </note>
или
<note> <date>xxx</date> ... </note>
?
Некоторые идеи можно найти по адресу:
<http://www.oasis-open.org/cover/elementsAndAttrs.html>
xmlfaqATxmlhackDOTru
Перевод "содержательной части"
<http://www.oasis-open.org/cover/elementsAndAttrs.html> и
дополнительные мысли есть в форумах xmlhack.ru:
<http://xmlhack.ru/forum/xml/YaBB.pl?board=todo;action=display;num
=1030650177>. Этот вопрос также обсуждался в fido7.ru.xml:
<http://raleigh.ru/XML/forum/discussion.php?article=1032872443@f1.
n5051.z2.ftn&mode=plain>.
7764 Прочтений • [Русский XML FAQ (web xml faq php java)] [08.05.2012] [Комментариев: 0]