Модераторы: diadiavova
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Переменные в XSL-преобразовании 
V
    Опции темы
batigoal
Дата 9.1.2007, 11:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Нелетучий Мыш
****


Профиль
Группа: Участник Клуба
Сообщений: 6423
Регистрация: 28.12.2004
Где: Санктъ-Петербургъ

Репутация: 1
Всего: 151



Такая задача. Есть XML-документ такого плана:
Код

<root>
  <node>first</node>
  <node>second</node>
  <node>third</node>
</root>


Необходимо сделать преобразование, которое сконкатенирует значение узлов node, НО! только до тех пор, пока не будет превышена максимальная длина строки. Т.е. если мы положим максимальную длину строки, например, 14 символов, то на выходе должно быть вот такое:
Код

first, second

без третьего элемента.

Если бы xsl:variable был "настоящей" переменной, то все было бы ясно, но как обойтись без этого - не понимаю.

Это сообщение отредактировал(а) batigoal - 9.1.2007, 11:47


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа" (Р. Шекли)
ЖоржЖЖ
PM WWW   Вверх
maxim1000
Дата 9.1.2007, 12:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 7
Всего: 110



можно попробовать так:
Код

<xsl:template name="concate">
    <xsl:param name="firstindex">
    <xsl:param name="maxlength">
    <xsl:if test="$first<count(node) and length(node[$firstindex])<$maxlength">
        <xsl:value-of select="node[$firstindex]"/>
        <xsl:call-template name="concate">
            <xsl:with-param name="firstindex" select="$firstindex+1"/>
            <xsl:with-param name="maxlength" select="$maxlength-length(node[$firstindex])"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>


Добавлено @ 12:10 
т.е. выводим первый элемент и остальные, если нужно
для остальных применяем то же самое правило...

Добавлено @ 12:10 
(правда, насчёт функции length не уверен, а в спецификацию лезть лень smile )

Добавлено @ 12:11 
P.S. не тестировал smile


--------------------
qqq
PM WWW   Вверх
batigoal
Дата 9.1.2007, 12:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Нелетучий Мыш
****


Профиль
Группа: Участник Клуба
Сообщений: 6423
Регистрация: 28.12.2004
Где: Санктъ-Петербургъ

Репутация: 1
Всего: 151



maxim1000, идея вроде понятна, спасибо.
Получается очень жестко, блин. Я подозреваю, это будет медленно работать а нам производительность важна. Попробую перенести это преобразование в Java-часть.

Добавлено @ 12:27 
Цитата(maxim1000 @  9.1.2007,  13:09 Найти цитируемый пост)
(правда, насчёт функции length не уверен, а в спецификацию лезть лень smile )

string-length()


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа" (Р. Шекли)
ЖоржЖЖ
PM WWW   Вверх
maxim1000
Дата 9.1.2007, 13:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 7
Всего: 110



Цитата(batigoal @  9.1.2007,  11:27 Найти цитируемый пост)
Я подозреваю, это будет медленно работать а нам производительность важна.

а почему?


--------------------
qqq
PM WWW   Вверх
batigoal
Дата 9.1.2007, 13:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Нелетучий Мыш
****


Профиль
Группа: Участник Клуба
Сообщений: 6423
Регистрация: 28.12.2004
Где: Санктъ-Петербургъ

Репутация: 1
Всего: 151



Цитата(maxim1000 @  9.1.2007,  14:08 Найти цитируемый пост)
а почему? 

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

Добавлено @ 13:45 
В любом случае, проэкспериментировать можно.

Это сообщение отредактировал(а) batigoal - 9.1.2007, 13:45


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа" (Р. Шекли)
ЖоржЖЖ
PM WWW   Вверх
maxim1000
Дата 9.1.2007, 14:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 7
Всего: 110



сама по себе рекурсия, особенно хвостовая, вполне может быть и непрожорливой к ресурсам
хот, конечно, всё от реализации зависит...


--------------------
qqq
PM WWW   Вверх
batigoal
Дата 11.1.2007, 15:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Нелетучий Мыш
****


Профиль
Группа: Участник Клуба
Сообщений: 6423
Регистрация: 28.12.2004
Где: Санктъ-Петербургъ

Репутация: 1
Всего: 151



Выкладываю конечный вариант (немного избыточный, из-за моих экспериментов).

Исходный XML содержит имена и фамилии актеров. Необходимо "склеить" фктеров в одну строку с ограниченной длиной.

Исходный XML:
Код

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <program title="prog1">
        <Actor ID="6782" Category="Schauspieler" Name="Grant" Role="Tom Winston" Surname="Cary" />
        <Actor ID="8708" Category="Schauspieler" Name="Loren" RollenName="Cinzia Zaccardi" Surname="Sophia"/>
        <Actor ID="3631" Category="Schauspieler" Name="Hyer" RollenName="Carolyn Gibson" Surname="Martha" />
    </program>
    <program title="prog2">
        <Actor ID="6783" Category="Schauspieler" Name="Jan Joseph" Role="Rudi Wurlitzer" Surname="Liefers"/>
        <Actor ID="8701" Category="Schauspieler" Name="Tiel" RollenName="Martin Brest" Surname="Schweiger" />
        <Actor ID="3634" Category="Schauspieler" Name="Moritz" RollenName="Arabian" Surname="Bleibtroy" />
    </program>
</root>


Преобразование:
Код

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
    
    <xsl:template match="root">
        <SOME_ROOT>
            <xsl:for-each select="program">
                <PROGRAM>
                    <TITLE>
                        <xsl:value-of select="@title"/>
                    </TITLE>
                    <ACTORS>
                        <xsl:call-template name="concate_actors">
                            <xsl:with-param name="current_index" select="1"/>
                            <xsl:with-param name="max_length" select="53"/>
                        </xsl:call-template>
                    </ACTORS>
                </PROGRAM>
            </xsl:for-each>
        </SOME_ROOT>
    </xsl:template>
    
    <xsl:template name="concate_actors">
        <xsl:param name="current_index"/>
        <xsl:param name="max_length"/>
        
        <xsl:variable name="actor">
            <xsl:if test="not ($current_index = 1)">
                <xsl:text>, </xsl:text>
            </xsl:if>
            <xsl:value-of select="./Actor[$current_index]/@Name"/>
            <xsl:text> </xsl:text>
            <xsl:value-of select="./Actor[$current_index]/@Surname"/>
        </xsl:variable>
        
        <xsl:if test="$current_index &lt; count(Actor)+1 and string-length($actor) &lt; $max_length">
            <xsl:value-of select="$actor"/>
            <xsl:call-template name="concate_actors">
                <xsl:with-param name="current_index" select="$current_index+1"/>
                <xsl:with-param name="max_length" select="$max_length - string-length($actor)"/>
            </xsl:call-template>
        </xsl:if>
    </xsl:template>
    
</xsl:stylesheet>


Результат:
Код

<?xml version="1.0" encoding="UTF-8"?>
<SOME_ROOT xmlns:fo="http://www.w3.org/1999/XSL/Format">
    <PROGRAM>
        <TITLE>prog1</TITLE>
        <ACTORS>Grant Cary, Loren Sophia, Hyer Martha</ACTORS>
    </PROGRAM>
    <PROGRAM>
        <TITLE>prog2</TITLE>
        <ACTORS>Jan Joseph Liefers, Tiel Schweiger</ACTORS>
    </PROGRAM>
</SOME_ROOT>


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


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа" (Р. Шекли)
ЖоржЖЖ
PM WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "XML/XSLT"
diadiavova

Прежде чем опубликовать вопрос, попробуйте воспользоваться поиском - возможно тема уже поднималась.

Также рекомендуем Вам зайти в раздел FAQ ,раздел дополняется и, возможно, там вы увидите готовое решение.

Для ответов на часто задаваемые вопросы существует FAQ раздела. Новости можно публиковать в разделе новостей. Для статей так же есть специальный раздел

Желаем удачи в Вашем деле!


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, diadiavova.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | XML, XSL | Следующая тема »


 




[ Время генерации скрипта: 0.1474 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.