Войти

Показать полную графическую версию : Что еще можно сделать с XML + XSLT + XSL


Страниц : 1 2 3 4 5 6 7 8 [9] 10 11 12 13

vadimiron
02-06-2006, 13:16
А как это нужно применять в моём случае? Всё равно переменные нигде не принимаются
Тип объекта, а значит и его xsl, лежит в глобальной переменной

Я пока только до такого дошёл
<xsl:choose>
<xsl:when test="$gt=image"><xsl:apply-templates mode="image"/></xsl:when>
<xsl:when test="$gt=audio"><xsl:apply-templates mode="audio"/></xsl:when>
</xsl:choose>

Vlad Drakula
02-06-2006, 13:21
vadimiron
вот к примеру здесь: http://soft.oszone.net/
есть нода programm она одна и таже на всех страницах, и XSL файл один и тот же...
но веть отображаются по разнаму в зависимости от того какой тип страницы показывается...

vadimiron
02-06-2006, 13:36
Честно говоря, там я только XTML код вижу, но не XSL
Я понимаю как использовать mode, но я не понимаю только одного, как я могу выбирать mode в зависимости от переменной
xsl:apply-templates всё равно не разрешает mode как переменная

Vlad Drakula
02-06-2006, 13:52
vadimiron
Честно говоря, там я только XTML код вижу, но не XSL
логично... т.к. ты видишь лошь результат XSL преобразования...

Я понимаю как использовать mode, но я не понимаю только одного, как я могу выбирать mode в зависимости от переменной
xsl:apply-templates всё равно не разрешает mode как переменная

как на счет такого решения:



<xsl:choose>
<xsl:when test="*">
<xsl:apply-templates select="*" mode="*"/>
</xsl:when>
<xsl:when test="*">
<xsl:apply-templates select="*" mode="*"/>
</xsl:when>
<xsl:when test="*">
<xsl:apply-templates select="*" mode="*"/>
</xsl:when>
<xsl:when test="*">
<xsl:apply-templates select="*" mode="*"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="*" mode="*"/>
</xsl:otherwise>
</xsl:choose>

vadimiron
02-06-2006, 13:56
Ну да, в общем то я так и сделал (мой пост выше) :)

Vlad Drakula
02-06-2006, 14:01
vadimiron
Ну да, в общем то я так и сделал (мой пост выше)
чего то я прогладел...

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

Vlad Drakula
03-06-2006, 23:18
к вопросу vadimiron о передаче параметров в шаблон, решил поделиться своими наработками...

когда в шаблон нужно передовать много информации ее наверное лучьше писывать просто отдельный "спец" блоком во входной XML тогда это позволит на много шире использовать ее в XPath запросах!

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

Vlad Drakula
12-06-2006, 17:34
тут возникал вопрос о том как можно выдирать какиенибуть данные из XML, и нашол следуещее решение:



<?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" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:xdt="http://www.w3.org/2005/xpath-datatypes">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:for-each select="//node()[name() = 'country']">
<xsl:value-of select="concat('$countryDirs[] = &quot;', @name, '&quot;;')"/>
</xsl:for-each>
<xsl:for-each select="//node()[name() = 'info']">
<xsl:value-of select="concat('$infoDirs[] = &quot;', ./../../node()/@name, '/', @name, '&quot;;')"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>





<?
function xml2html($f1, $f2, $debug = 0)
{
$XML = implode ('', file($f1));
$XSL = implode ('', file($f2));

$arguments = array('/_xml' => $XML,'/_xsl' => $XSL);

// Allocate a new XSLT processor
$xh = xslt_create();

// Process the document
$HTML = xslt_process($xh, 'arg:/_xml', 'arg:/_xsl', NULL, $arguments);
if($debug)
{
header('Content-type: application/xml');
print $XML;
}
else
{
if ($HTML)
{
return str_replace('&', '&', $HTML);
}
else
{
echo " Sorry, sample.xml could not be transformed by sample.xsl into";
echo " the \$XML variable the reason is that " . xslt_error($xh);
echo " and the error code is " . xslt_errno($xh);
}
}
xslt_free($xh);
}

eval(xml2html('./geo.xml', './geo1.xslt'));
?>
<pre>
<?
print_r($countryDirs);
print_r($infoDirs);
?>
</pre>



вроде все очень просто и понятно...

3kLiN
03-08-2006, 23:03
судя по информации на сайте php.net с php5 библиотека XSLT на основе анализатора sablotron не поставляется :(
поставляется некотоый аналог - ОО-мая библиотека XSL на основе libxslt . кто пользуется таковой или все на php4 сидят? приведи простенький примерчик кода, plz

benya
04-08-2006, 11:31
3kLiN
А что есть большая разница? Эти библиотеки делают одно и тоже. Там только поменять небольшой кусочек в PHP где происходит трансформация.

3kLiN
04-08-2006, 12:27
benya, да, thnx. я уже нашёл примерчик. в XSL нужно ещё создавать DomDocument`ы. это и сбило с толку поначалу. спасибо php.net за наше счастливое детство :)

3kLiN
04-08-2006, 17:50
господа, помогайте. уже два часа кручу-верчу никак сообразить не хочу :(
задача тривиальная: нужно построить pager. есть общее кол-во страниц и номер текущей страницы. как с помощью xslt выдать пейджер а-ля на этом форуме (т.е. активная страница, а справа и слева, если нужно, по n ссылок) ?

benya
12-08-2006, 17:11
3kLiN
А я как раз несколько месяцев назад делал тоже самое. Сделал нечто такого:


<!-- СТРАНИЦЫ -->
<xsl:template match="pages" mode="pages">
<xsl:variable name="count" select="3"/>
<xsl:variable name="sel" select="@sel"/>
<xsl:variable name="item" select="item[position() = $sel]"/>
<xsl:variable name="items" select="$item/preceding-sibling::item[position() &lt;= $count]| $item | $item/following-sibling::item[position() &lt;= $count]"/>
<xsl:variable name="last" select="count(item)"/>
<xsl:variable name="allmess" select="@allmess"/>
<xsl:variable name="mess" select="@mess"/>
<xsl:if test="$last > 1">
<table border="0" cellspacing="1" cellpadding="0">
<tr>
<td>
<span class="lang_link1">
<xsl:value-of select="concat('Страница',' ',$sel,' ','из',' ',$last)"/>
<xsl:text> </xsl:text>
</span>
</td>
<xsl:if test="not($sel = '1')">
<td>
<a href="page.html" class="page" title="На первую страницу">««</a>
</td>
</xsl:if>
<xsl:if test="not($sel = '1')">
<td>
<a href="page{$sel - 1}.html" class="page" title="Предыдущая страница ({$sel - 1})">«</a>
</td>
</xsl:if>
<xsl:for-each select="$items">
<xsl:variable name="pos">
<xsl:number/>
</xsl:variable>
<xsl:variable name="to" select="($pos * $mess) - $mess"/>
<xsl:variable name="a" select="($sel * $mess) div $mess + 1"/>
<xsl:variable name="psst" select="$to + 1"/>
<xsl:variable name="psend" select="$psst + ($mess - 1)"/>
<td>
<a>
<xsl:attribute name="title"><xsl:choose><xsl:when test="$a != $pos"><xsl:choose><xsl:when test="$allmess = $psst"><xsl:value-of select="concat('Страница',' ',$pos,' ','(',$allmess,' ','из',' ',$allmess,')')"/></xsl:when><xsl:when test="$psend > $allmess"><xsl:value-of select="concat('Страница',' ',$pos,' ','(','с',' ',$psst,' ','по',' ',$allmess,' ','из',' ',$allmess,')')"/></xsl:when><xsl:otherwise><xsl:value-of select="concat('Страница',' ',$pos,' ','(','с',' ',$psst,' ','по',' ',$psend,' ','из',' ',$allmess,')')"/></xsl:otherwise></xsl:choose></xsl:when><xsl:when test="$allmess = $psst"><xsl:value-of select="concat('Страница',' ',$pos,' ','(',$allmess,' ','из',' ',$allmess,')')"/></xsl:when><xsl:when test="$psend > $allmess"><xsl:value-of select="concat('Страница',' ',$pos,' ','(','с',' ',$psst,' ','по',' ',$allmess,' ','из',' ',$allmess,')')"/></xsl:when><xsl:otherwise><xsl:value-of select="concat('Страница',' ',$pos,' ','(','с',' ',$psst,' ','по',' ',$psend,' ','из',' ',$allmess,')')"/></xsl:otherwise></xsl:choose></xsl:attribute>
<xsl:attribute name="href"><xsl:value-of select="concat('page',$pos,'.html')"/></xsl:attribute>
<xsl:attribute name="class"><xsl:choose><xsl:when test="$pos = $sel">page-a</xsl:when><xsl:otherwise>page</xsl:otherwise></xsl:choose></xsl:attribute>
<xsl:value-of select="$pos"/>
</a>
</td>
</xsl:for-each>
<xsl:if test="not($sel = $last)">
<td>
<a href="page{$sel + 1}.html" class="page" title="Следующая страница ({$sel + 1})">»</a>
</td>
</xsl:if>
<xsl:if test="not($sel = $last)">
<td>
<a href="page{$last}.html" class="page" title="Последняя страница ({$last})">»»</a>
</td>
</xsl:if>
</tr>
</table>
</xsl:if>
</xsl:template>
<!-- СТРАНИЦЫ -->

Лишнюю HTML разметку можно выкинуть ;)

На вход нужно подать вот такую структуру XML:


<pages sel="1" allmess="41" mess="5">
<item/>
<item/>
<item/>
<item/>
<item/>
<item/>
<item/>
<item/>
<item/>
</pages>




Вызывается как-то так:

<xsl:apply-templates select="pages" mode="pages"/>

Не факт что мой пример правильный с точки зрения производительности, правильности и тд. Наша профессура из форума может начинать критиковать :tease:
Можно было и XML попроще передать. Но...пример работает и я не заморачивался.
Результат: тоже самое - список пейджей как на этом форуме.

Vlad Drakula
12-08-2006, 23:26
чтож представлю свой вариант решения этой задачи...

на входе:


<pages sel="2" mess="2">
<item/>
<item/>
<item/>
<item/>
<item/>
<item/>
<item/>
<item/>
<item/>
</pages>



шаблон:


<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<xsl:call-template name="nav"/>
</xsl:template>
<xsl:template name="nav">
<xsl:apply-templates select="//pages" mode="nav"/>
</xsl:template>
<xsl:template match="pages" mode="nav">
<xsl:variable name="start" select="@sel - @mess"/>
<xsl:variable name="end" select="@sel + @mess"/>
<xsl:variable name="prev" select="@sel - 1"/>
<xsl:variable name="next" select="@sel + 1"/>
<xsl:variable name="all" select="count(item)"/>
<table border="1">
<tbody>
<tr>
<td>
<xsl:value-of select="concat(@sel, ' of ', $all)"/>
</td>
<xsl:if test="@sel != 1">
<xsl:apply-templates select="item[1]" mode="nav_f" />
<xsl:apply-templates select="item[$prev]" mode="nav_p" />
</xsl:if>
<xsl:apply-templates select="item[position() &gt;= $start and position() &lt;= $end]" mode="nav" />
<xsl:if test="$end &lt; $all">
<xsl:apply-templates select="item[$next]" mode="nav_n" />
<xsl:apply-templates select="item[$all]" mode="nav_l" />
</xsl:if>
</tr>
</tbody>
</table>
</xsl:template>
<xsl:template match="item" mode="nav">
<td>
<xsl:value-of select="position()"/>
</td>
</xsl:template>
<xsl:template match="item" mode="nav_f">
<td>
<xsl:text>f</xsl:text>
</td>
</xsl:template>
<xsl:template match="item" mode="nav_l">
<td>
<xsl:text>last</xsl:text>
</td>
</xsl:template>
<xsl:template match="item" mode="nav_p">
<td>
<xsl:text>&lt;</xsl:text>
</td>
</xsl:template>
<xsl:template match="item" mode="nav_n">
<td>
<xsl:text>&gt;</xsl:text>
</td>
</xsl:template>
</xsl:stylesheet>



benya
вы бы хоть предупредели что ваш шаблон использует XSL2.0

<xsl:variable name="item" select="item[position() = $sel]"/> - этого в XSL1.0 вроде как нету... там переменные только текстовые...

benya
я наложил структирирование на ваш пример и пофиксил пару багов(очевидных) в шаблоне.

E-mail
12-08-2006, 23:52
http://tex.msu.ru/works/mmlbrowsers/
http://tex.msu.ru/works/mmlbrowsers/test.xhtml

попробывал я в фаерфоксе 1506 открыть, отображает только исходный код, непойму откуда взялись эти скриншоты, или надо произвести какието настройки браузеру? плагины?

В ie sp2 хоть выдает ошибку The XML page cannot be displayed :)

opera 901 аналагично лисице(

хотя наверное все дело в content-type.

3kLiN
13-08-2006, 00:08
benya, Vlad Drakula, спасибо за примеры, но я уже решил с помощью рекурсивных вызовов <xsl:call-template ... />

benya
13-08-2006, 12:31
Vlad Drakula,
XSL2.0 вроде как нету, а с библиотекой LibXSLT 1.0 вроде как работает ;)

И что за очевидные баги ты заметил?

Vlad Drakula
14-08-2006, 23:11
benya
И что за очевидные баги ты заметил?
а... у тебя были не заменены "<" на "&lt;"

XSL2.0 вроде как нету, а с библиотекой LibXSLT 1.0 вроде как работает
а к примеру MSXml наверное не скушает...
ноды как параметры передавать может но как переменные нет... поддержка полноценных переменных появилось лишь в XSLT2.0 (в стандарте)

просто мне пришлось как то проводить сравнения меджу возможностями XSLT1.0 и XSLT2.0

3kLiN
рекурсия это в принцепе хорошо... при использовании XSLT ей нужно хорошо владеть иначе никак... но для такой задачи по моему это как из пушки по воробьям... нужно еще задумываться и о перфомансе приложения!


в связи с тем что тема пейджинга оказалась интересна привожу еще один шаблон... решение достаточно элегантное:


<xsl:template name="pages">
<xsl:param name="pages" select="ceiling(count(//news) div 15)"/>
<xsl:param name="page" select="2"/>
<xsl:text> | </xsl:text>
<a href="./news{$page}.html">
<xsl:value-of select="$page"/>
</a>
<xsl:if test="$page &lt; $pages">
<xsl:call-template name="pages">
<xsl:with-param name="pages" select="$pages"/>
<xsl:with-param name="page" select="$page + 1"/>
</xsl:call-template>
</xsl:if>
</xsl:template>



вот к приму у вас есть набор новостей вам их нужно разбирать на страницы по 15 новостей на страницу...

вызывается шаблон следующим образом:



<fieldset>
<legend>Страницы:</legend>
<a href="./index.html">
<b>1</b>
</a>
<xsl:call-template name="pages"/>
</fieldset>



E-mail
Решением этой проблемы может служить использование специальных XSLT-стилей "XSLT stylesheets for MathML". Такой подход возможен, так как поддержка XSLT-трансформаций встроена в браузер. Для этого надо скачать набор XSLT-стилей и в первой строчке нашей страницы указать ссылку на заглавный файл mathml.xsl:

<?xml-stylesheet type="text/xsl" href="mathml.xsl"?>

benya
15-08-2006, 19:54
Vlad Drakula,
Кстати, я тоже как-то хотел так сделать, но вызывание теплейта из самого темплейта у меня вызывает ошибку, хотя в книгах это широко используют. Поэтому пришлось от такого метода отказаться.

Vlad Drakula
16-08-2006, 10:35
benya
Кстати, я тоже как-то хотел так сделать, но вызывание теплейта из самого темплейта у меня вызывает ошибку, хотя в книгах это широко используют. Поэтому пришлось от такого метода отказаться.
либо вы что то не так делали либо у вас совсем не правильный XSLT процессор!




© OSzone.net 2001-2012