powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / XML, XSL, XPath, XQuery [игнор отключен] [закрыт для гостей] / XSLT: Как сделать вывод таблицы в несколько столбцов
22 сообщений из 22, страница 1 из 1
XSLT: Как сделать вывод таблицы в несколько столбцов
    #33805734
step-spb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть xml-файл:

<items>
<item>a</item>
<item>b</item>
<item>c</item>
<item>d</item>
</items>

Нужно построить html-страницу на основе этих данных.

Понятно, как при помощи XSLT построить таблицу, содержащую данные построчно:
<tr><td>a</td></tr>
<tr><td>b</td></tr>
<tr><td>c</td></tr>
<tr><td>d</td></tr>

Я же хочу построить таблицу, содержащую данные в несколько столбцов:

<tr>
<td>a</td>
<td>b</td>
</tr>
<tr>
<td>c</td>
<td>d</td>
</tr>

Рука тянется написать что-то типа

<xsl:if test="position() mod 2 = 0">
</tr><tr>
</xsl:if>

но это не работает. С горя пробовал всякое:

<xsl:value-of select="'</tr><tr>'" />
<xsl:value-of select="'</tr><tr>'" />
<xsl:text></tr><tr></xsl:text>

Как быть в этой ситуации?
Заранее спасибо.
...
Рейтинг: 0 / 0
XSLT: Как сделать вывод таблицы в несколько столбцов
    #33806145
beard-electronic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я бы сделал так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:variable name="colNum" select="2" />

   <xsl:template match="/items">
      <table>
         <xsl:apply-templates select="item[position() mod $colNum = 1]" mode="row" />
      </table>
   </xsl:template>

   <xsl:template match="item" mode="row">
      <TR>
         <xsl:apply-templates select="self::node()" mode="col" />

         <xsl:apply-templates select="following-sibling::item[position()<$colNum]" mode="col" />
      </TR>
   </xsl:template>

   <xsl:template match="item" mode="col">
      <TD>
         <xsl:value-of select="." />
      </TD>
   </xsl:template>
</xsl:stylesheet>
хотя как-то кривовато...
...
Рейтинг: 0 / 0
XSLT: Как сделать вывод таблицы в несколько столбцов
    #33806519
step-spb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Почти заработало.

Что не получается:
Я должен сортировать выводимые строки, причем пользователь может выбирать, по каким полям это делать.

Я поступал так:

<table>
<xsl:for-each select="items/item">
<xsl:sort order="ascending" select="name"/>
...

Затем программно модифицировал select в xsl:sort-е и перестраивал таблицу.

Но как сделать сортировку в приведенном примере?
...
Рейтинг: 0 / 0
XSLT: Как сделать вывод таблицы в несколько столбцов
    #33806610
beard-electronic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
apply-templates тоже поддерживают элемент
xsl:sort.
Встречный вопрос: для данного примера в случае descending каков будет вывод:
d c
b a
?
...
Рейтинг: 0 / 0
XSLT: Как сделать вывод таблицы в несколько столбцов
    #33807036
beard-electronic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вобщем, можно поступить, как пытались вы c горя, только надо было использовать
атрибут disable-output-escaping у value-of или у text:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
   <xsl:variable name="colNum" select="2" />

   <xsl:variable name="ot_TR"><TR></xsl:variable>

   <xsl:variable name="ct_TR"></TR></xsl:variable>

   <xsl:template match="/items">
      <table>
         <xsl:for-each select="item">
            <xsl:sort order="descending" />

            <xsl:if test="position() mod $colNum = 1">
               <xsl:value-of select="$ot_TR" disable-output-escaping="yes" />
            </xsl:if>

            <TD>
               <xsl:value-of select="." />
            </TD>

            <xsl:if test="position() mod $colNum = 0">
               <xsl:value-of select="$ct_TR" disable-output-escaping="yes" />
            </xsl:if>

          </xsl:for-each>
      </table>
   </xsl:template>
Но это не есть хорошо,
а как хорошо, я пока не придумал (ибо вечер, и только корявые способы лезут в голову)
...
Рейтинг: 0 / 0
XSLT: Как сделать вывод таблицы в несколько столбцов
    #33807313
beard-electronic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сорри, где написано
Код: plaintext
1.
2.
3.
   <xsl:variable name="ot_TR"><TR></xsl:variable>

   <xsl:variable name="ct_TR"></TR></xsl:variable>
< и > вокруг TR следует читать как
& lt; и & gt; соответственно (пробел убрать)
- не знал, что эскейп-последовательности дизебляться при создании нового сообщения
...
Рейтинг: 0 / 0
XSLT: Как сделать вывод таблицы в несколько столбцов
    #33807831
Виктор1111
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Товарисчи! У самого похожая проблема, возможно смогу ее решить с вашей помощью, но... Прошу прощения за, возможно, клинический кретинизм, но что означает конструкция:

<xsl:if test="position() mod $colNum = 1">


а именно, "= 1" не понимаю...
...
Рейтинг: 0 / 0
XSLT: Как сделать вывод таблицы в несколько столбцов
    #33808489
beard-electronic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
position() - текущая позиция, номер выбранного узла из select (начинается с 1)
mod - остаток от деления.
Отсюда мы хотим узнать, что остаток от деления равен 1:
position() mod $colNum = 1
значит, что position() может быть 1, $colNum + 1, $colNum * 2 + 1, ... $colNum * N + 1 .....
Это для того, чтобы понять, когда переходить на новую строку в таблице, у которой
ровно $colNum столбцов
...
Рейтинг: 0 / 0
XSLT: Как сделать вывод таблицы в несколько столбцов
    #33810889
Виктор1111
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
beard-electronicposition() - текущая позиция, номер выбранного узла из select (начинается с 1)
mod - остаток от деления.
Отсюда мы хотим узнать, что остаток от деления равен 1:
position() mod $colNum = 1
значит, что position() может быть 1, $colNum + 1, $colNum * 2 + 1, ... $colNum * N + 1 .....
Это для того, чтобы понять, когда переходить на новую строку в таблице, у которой
ровно $colNum столбцов

А, ну слишком мудрено объяснил, но вроде понял - т.е. position() mod $colNum возвращает остаток от деления... Вот это то я и не знал...

А вот свою проблему я так и не решил, у меня другая структура, типа:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
<items>
<item name="a">
  <item name="b">
    <item name="c"></item>
    <item name="d"></item>
  </item>
</item>
<item name="e"></item>
</items>

То есть почти то же самое, но многоуровневое дерево, которое считывается последовательно. И position() тут уже не пашет совсем, так как выдает позицию в пределах подчинению родительского элемента (то есть из вышеприведенной структуры для элемента с name=a и name=b position() = 1, в обоих случаях). Мне бы как-нибудь счетчик организовать - но вот что-то я притупляю, как нибудь это можно на xsl сделать?
...
Рейтинг: 0 / 0
XSLT: Как сделать вывод таблицы в несколько столбцов
    #33811310
beard-electronic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Виктор1111
А, ну слишком мудрено объяснил, но вроде понял - т.е. position() mod $colNum возвращает остаток от деления... Вот это то я и не знал...

Я тоже не знал, что вы не знаете, поэтому так и написал (видать, осталось от преподавания в школе :) )
Виктор1111
То есть почти то же самое, но многоуровневое дерево, которое считывается последовательно.

Вы бы более подробно описали, как вы последовательно читаете (и почему) - желательно код свое привести. Счетчик-то можно многими способами забабахать -
главное знать, откуда плясать.
...
Рейтинг: 0 / 0
XSLT: Как сделать вывод таблицы в несколько столбцов
    #33811516
Виктор1111
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Да дело в том, что у меня xml генерится уже написанной сторонними разработчиками громадной штукой - и xml этот - это структура сайта с множеством атрибутов и тегов, куды я добавил поле с картинкой. И мне картинки (там где они есть) надо вывести в 2 колонки - что-то типа баннеров, причем таких страниц на сайте несколько, где такая штука выводится - причем картинки берутся только для нижестоящих уровней от текущей страницы. Я бы конечно мог сделать отдельное хранилище для этих картинок - и тогда не было бы многоуровневости - но потом админить сложно будет... Поэтому привязываю к тому что есть.

Каждый элемент структуры содержится в теге "structure". Поэтому первым делом вызывается шаблон для всех элементов structure под текущей веткой в структуре меню.

В нем куча проверок - пока еще не до конца дописаны, там еще подзаголовки надо выводить между картинками, но это все семечки - это я допишу без особых проблем... А вот загвозвочка с самим выводом баннера (для читабельности вынесено в отдельный шаблон "banner"). Когда структурка была простенькая - все нормально работало, ибо position() выдавал желаемое, но как только структура сайта усложнилась и появилось больше уровней вложенности - position() стал выдавать совсем уже не то... Мне бы по-хорошему, тупо передавать в шаблон "banner" некоторый счетчик - и не position() смотреть - а по его значению чет/нечет определять... Но как такой счетчик сделать? Видел я примеры с рекурсией - но что-то как-то не могу сообразить, как здесь это применить...

Привожу весь свой xsl:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
<?xml version="1.0" encoding="windows-1251"?>
<!DOCTYPE xsl:stylesheet>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" encoding="Windows-1251"/>

<!-- Получаем ID папы текущей страницы и записываем в переменную $parent_ID -->
<xsl:param name="parent_ID" select=".//structure[@id=current_structure_id]/id_parent"/>

<xsl:template match="/document">
		<table border="0">
		<xsl:apply-templates select="structure[level = 0 and .//@id = current_structure_id]"/>
		</table>
</xsl:template>

<xsl:template match="structure">

	<xsl:param name="banner" select="propertys/property[@name='banner']/property_file_path"/>
	<xsl:param name="isHeader" select="propertys/property[@name='banners_isHeader']/value"/>
	
	<xsl:if test="show_link=1">
		
		<!-- нулевой уровень (корневые элементы) не выводим, а также не выводим элементы ниже 1-го уровня, если у них нет подчиненного элемента текущего-->	
		<xsl:if test=" (level != 0) ">
			<ul>
			<xsl:if test="show_link=1">
			
				<xsl:choose>
				<xsl:when test = "$isHeader = 1">
					<tr><td>
						<h1><xsl:value-of disable-output-escaping="yes" select="name"/>  </h1>
					</td></tr>
				</xsl:when>
				<xsl:otherwise>
				</xsl:otherwise>
				</xsl:choose>
				
				<xsl:if test = "$banner != ''">
					<xsl:call-template name="banner">
						<xsl:with-param name="link" select="link"/>
						<xsl:with-param name="img" select="$banner"/>
						<xsl:with-param name="name" select="name"/>
					</xsl:call-template>
				</xsl:if>
						
				
				
			</xsl:if>
				
			<xsl:apply-templates select="structure"/>
			</ul>
		</xsl:if>
		<xsl:if test="level = 0">
			<xsl:apply-templates select="structure"/>
		</xsl:if>			
		
	</xsl:if>
</xsl:template>

<xsl:template name = "banner">
	<xsl:param name="link"/>
	<xsl:param name="img"/>
	<xsl:param name="name"/>

	<xsl:if test = "position() div 2 != round(position() div 2)">
		<xsl:text disable-output-escaping="yes">
		<![CDATA[
		<tr>
		]]>
		</xsl:text>
	</xsl:if>
		
			<td width="45%">
				<div onclick="javascript:document.location='{$link}'" style="cursor:hand">
					<table border="0" cellpadding="0" cellspacing="0">
						<tr><td width="225" height="72"><img src="/{$img}" border="0" alt=""></img></td></tr>
						<tr><td height="1" bgcolor="#000000"></td></tr>
						<tr><td bgcolor="#E5E4FF"><table cellspacing="1" cellpadding="1" border="0"><tr><td><strong>
							<xsl:value-of disable-output-escaping="yes" select="$name"/>
						</strong></td></tr></table></td></tr>
						<tr><td height="1" bgcolor="#000000"></td></tr>
					</table><br/>
				</div>
			</td>
		
	<xsl:if test = "position() div 2 = round(position() div 2)">
		<xsl:text disable-output-escaping="yes">
		<![CDATA[
		</tr>
		]]>
		</xsl:text>
	</xsl:if>
	
</xsl:template>

</xsl:stylesheet>

...
Рейтинг: 0 / 0
XSLT: Как сделать вывод таблицы в несколько столбцов
    #33811635
step-spb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо, заработало
...
Рейтинг: 0 / 0
XSLT: Как сделать вывод таблицы в несколько столбцов
    #33811917
beard-electronic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Давайте упростим задачу, так как еще бы неплохо иметь пример xml, а он, как понимаю, большой.
вот что я понял из скрипта:
1. Выдираем по какому-то условию structure (level=0 ...) и производим какие-то действия над его потомками (как понимаю, у потомков уже не может быть level=0)/
Т.е. по сути мы работаем с таким деревом (для краткости structure := s):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
<s>
   <s />
   <s />
     ...
   <s>
      <s />
      <s>
         <s />
      </s>
      <s />
   </s>
   ...
</s>

<s>
   ...
   <s>
      <s />
      <s />
   </s>
   <s />
   ...
</s>
...
Для первых - ничего не делаем а для потомков:
2. если у них есть непустой элемент banner (сократим проперти до такого элемента), то выводим в итоговую таблицу с учетом разбиения на две колонки.

Я прав?

Если да, то мой совет - сразу выдирать нужные structure одним XPath выражением - что-то типа:
Код: plaintext
1.
2.
3.
<table border="0">
		<xsl:apply-templates select="structure[level = 0 and .//@id = current_structure_id and show_link=1]//structure"/>
		</table>
тогда position() можно будет использовать

PS: У вас еще два одинаковых вложенных условия
Код: plaintext
1.
<xsl:if test="show_link=1">
Явно второе будет всегда выполняться, так что его можно опустить :)
Хотя если мой совет прокатит, то эти условия уже не нужны
...
Рейтинг: 0 / 0
XSLT: Как сделать вывод таблицы в несколько столбцов
    #33814345
Виктор1111
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
По поводу 1 и 2 - так точно!

За выдирать сразу нужные structure - огромный респект! Теперь лучше понял как position() работает! Раньше имел неосторожность думать, что он дает позицию в структуре исходного xml, а не уже непосредственно в результате запроса...

Но вот вме равно не работает как должно: помимо баннеров должны выводиться еще и заголовки (то есть внешне - прерывается таблица, выводится заголовок и следующий элемент должен выводится слева, независимо от position()). Заголовки тоже берутся из structure - причем один structure может содежрать и баннер, и заголовок, или что-то не содержать... Короче говоря, если баннера нет, а есть заголовок, то этот заголовок тоже "пересчитывается" position()'ом.
Кроме того, после любого заголовка по-хорошему должен идти нечетный элемент...
Таким образом выходят баги, что выводится заголовок - а потом идет баннер, у которого position() уже = 2 (ну или любое четное число), а потому после него происходит переход на следующую строку таблицы:(( Пример смотрите тут (сразу после первого баннера перескакивает строка):

По-поводу лишних условий: приношу извинения - просто код набрасывал кусками из написанных ранее модулей - и как-то не успел внимательно прочитать:)) Сейчас подчистил...

В итоге получилось так:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
<?xml version="1.0" encoding="windows-1251"?>
<!DOCTYPE xsl:stylesheet>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" encoding="Windows-1251"/>

<xsl:template match="/document">
	<table border="0">
		<xsl:apply-templates select="structure[@id=current_structure_id]//structure[show_link=1 and (propertys/property[@name='banner']/property_file_path!='' or propertys/property[@name='banners_isHeader']/value=1)]"/>
	</table>
</xsl:template>

<xsl:template match="structure">

	<xsl:param name="banner" select="propertys/property[@name='banner']/property_file_path"/>
	<xsl:param name="isHeader" select="propertys/property[@name='banners_isHeader']/value"/>
		
	<ul>
			
	<xsl:if test = "$isHeader = 1">
		<tr><td>
			<h1><xsl:value-of disable-output-escaping="yes" select="name"/>  </h1>
		</td></tr>
	</xsl:if>

	<xsl:if test = "$banner != ''">
		<xsl:call-template name="banner">
			<xsl:with-param name="link" select="link"/>
			<xsl:with-param name="img" select="$banner"/>
			<xsl:with-param name="name" select="name"/>
		</xsl:call-template>
	</xsl:if>
	

	</ul>			
</xsl:template>

<xsl:template name = "banner">
	<xsl:param name="link"/>
	<xsl:param name="img"/>
	<xsl:param name="name"/>

	<xsl:if test = "position() div 2 != round(position() div 2)">
		<xsl:text disable-output-escaping="yes">
		<![CDATA[
		<tr>
		]]>
		</xsl:text>
	</xsl:if>
		
	<td width="45%">
	<div onclick="javascript:document.location='{$link}'" style="cursor:hand">
		<table border="0" cellpadding="0" cellspacing="0">
			<tr><td width="225" height="72"><img src="/{$img}" border="0" alt=""></img></td></tr>
			<tr><td height="1" bgcolor="#000000"></td></tr>
			<tr><td bgcolor="#E5E4FF"><table cellspacing="1" cellpadding="1" border="0"><tr><td><strong>
				<xsl:value-of disable-output-escaping="yes" select="$name"/>
			</strong>поз: <xsl:value-of disable-output-escaping="yes" select="position()"/></td></tr></table></td></tr>
			<tr><td height="1" bgcolor="#000000"></td></tr>
		</table><br/>
	</div>
	</td>
		
	<xsl:if test = "position() div 2 = round(position() div 2)">
		<xsl:text disable-output-escaping="yes">
		<![CDATA[
		</tr>
		]]>
		</xsl:text>
	</xsl:if>
	
</xsl:template>

</xsl:stylesheet>


Вот такие дела... Думал сделать 2 шаблона - один на заголовки, а один - на баннеры, и из первого вызывать второй, но между ними связи никакой нет - баннеры не обязательно находятся под текущем заголовком, все должно последовательно считываться... Приведу пример (упрощаю для читабельности структуру xml):

Код: plaintext
1.
2.
3.
4.
5.
<s name="s1" isHeader =  1  banner = "">
   <s name="s2" isHeader =  0  banner = "1.jpg" />
   <s name="s3" isHeader =  0  banner = "2.jpg" />
   <s name="s4" isHeader =  0  banner = "" />
</s>
<s name="s5" isHeader =  0  banner = "3.jpg" />

Этот xml должен быть выведен так: сначала выводится заголовок "s1", потом в первой строке таблицы 2 баннера "s2" и "s3". Потом с новой строки баннер "s5".
Со временем еще перед s5 надо вставить разделитель - но до этого я еще не дошел - просто типа вывести баннер без заголовка, но отделить от предыдущего раздела...

Ну так самое обидное, что сейчас выведется s2 в первую строку, s3 и s5 во-вторую. А если разбить на 2 шаблона - сначала выцепить заголовки, а потом уже выводить под ними баннеры - то я смогу вывести s2 и s3, но непонятно как выцепить s5...

Ну почему в xsl нет нормальных, человеческих переменных!?:((
...
Рейтинг: 0 / 0
XSLT: Как сделать вывод таблицы в несколько столбцов
    #33815003
beard-electronic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Получается, что надо учитывать предыдущий контент - значит есть два пути:
1. Каждый раз, перед тем как что-нибудь сделать, надо смотреть назад (каждый раз надо перековыривать предыдущие узлы - долго)
2. Вызывать шаблон конкретно для каждого следующего элемента с необходимыми
данными о том, что было сделано перед этим (память - много или мало, зависит от задачи).

Для вашего укороченного примера можно предложить нечто подобное (2 способ):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
<?xml version="1.0" encoding="windows-1251"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="html" indent="yes" encoding="Windows-1251" />

   <xsl:variable name="ot_TR">&lt;TR&gt;</xsl:variable>

   <xsl:variable name="ct_TR">&lt;/TR&gt;</xsl:variable>

   <xsl:variable name="structures" select="//s" />

   <xsl:variable name="total" select="count($structures)" />

   <xsl:template match="/document">
      <table border="0">
         <xsl:apply-templates select="$structures[1]" />
      </table>
   </xsl:template>

   <xsl:template match="s">
      <xsl:param name="elemCurPos" select="1" />

      <xsl:param name="tablePos" select="1" />

      <xsl:variable name="isHeader" select="@isHeader=1" />

      <xsl:choose>
         <xsl:when test="$isHeader">
            <xsl:apply-templates select="." mode="header">
               <xsl:with-param name="elemCurPos" select="$elemCurPos" />

               <xsl:with-param name="tablePos" select="$tablePos" />
            </xsl:apply-templates>
         </xsl:when>

         <xsl:otherwise>
            <xsl:apply-templates select="." mode="banner">
               <xsl:with-param name="elemCurPos" select="$elemCurPos" />

               <xsl:with-param name="tablePos" select="$tablePos" />
            </xsl:apply-templates>
         </xsl:otherwise>
      </xsl:choose>
   </xsl:template>

   <xsl:template match="s" mode="header">
      <xsl:param name="elemCurPos" select="1" />

      <xsl:param name="tablePos" select="1" />

      <xsl:if test="$tablePos=2">
         <xsl:value-of disable-output-escaping="yes" select="$ct_TR" />
      </xsl:if>

      <tr>
         <td>
            <h1>
               <xsl:value-of disable-output-escaping="yes" select="@name" />
            </h1>
         </td>
      </tr>

      <xsl:apply-templates select="." mode="banner">
         <xsl:with-param name="elemCurPos" select="$elemCurPos" />

         <xsl:with-param name="tablePos" select="1" />
      </xsl:apply-templates>
   </xsl:template>

   <xsl:template match="s" mode="banner">
      <xsl:param name="elemCurPos" select="1" />

      <xsl:param name="tablePos" select="1" />

      <xsl:variable name="banner" select="@banner" />

      <xsl:choose>
         <xsl:when test="$banner!=''">
            <xsl:if test="$tablePos=1">
               <xsl:value-of disable-output-escaping="yes" select="$ot_TR" />
            </xsl:if>

            <TD>
               <xsl:value-of select="$banner" />
            </TD>

            <xsl:if test="$tablePos=2">
               <xsl:value-of disable-output-escaping="yes" select="$ct_TR" />
            </xsl:if>

            <xsl:choose>
               <xsl:when test="$elemCurPos&lt;$total">
                  <xsl:apply-templates select="$structures[$elemCurPos+1]">
                     <xsl:with-param name="elemCurPos" select="$elemCurPos+1" />

                     <xsl:with-param name="tablePos" select="($tablePos mod 2) + 1" />
                  </xsl:apply-templates>
               </xsl:when>

               <xsl:otherwise>
                  <xsl:value-of disable-output-escaping="yes" select="$ct_TR" />
               </xsl:otherwise>
            </xsl:choose>
         </xsl:when>

         <xsl:otherwise>
            <xsl:choose>
               <xsl:when test="$elemCurPos&lt;$total">
                  <xsl:apply-templates select="$structures[$elemCurPos+1]">
                     <xsl:with-param name="elemCurPos" select="$elemCurPos+1" />

                     <xsl:with-param name="tablePos" select="$tablePos" />
                  </xsl:apply-templates>
               </xsl:when>

               <xsl:otherwise>
                  <xsl:value-of disable-output-escaping="yes" select="$ct_TR" />
               </xsl:otherwise>
            </xsl:choose>
         </xsl:otherwise>
      </xsl:choose>
   </xsl:template>
</xsl:stylesheet>
Идем по каждому элементу структуры отдельно (для удобства я вынес их всех в переменную, но если их много, то ради экономии памяти можно будет брать
следующий элемент исходя из контекста), если у элемента есть header, закрываем TR для баннеров, если уже был выведен один, выводим header.
Выводим в первую ячейку таблицы для баннеров текущий, если есть, передаем
следующему ноду инфо о том, что уже один баннер есть.
Далее, пока не встретим новый header, раскидываем баннеры в таблицу, исходя
из переданной инфы о текущей позиции в столбцах (1 или 2). И т.д.
...
Рейтинг: 0 / 0
XSLT: Как сделать вывод таблицы в несколько столбцов
    #33815056
beard-electronic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хотя можно "прямее" написать:
1. "Выдираем" все баннеры с текщего элемента до ближайшего с header-ом, группируем по 2 и выводим (не надо будет искусственно встявлять TR).
2. Продолжаем со следующего элемента (он как раз с header-ом будем) - выводим
header, выполняем пункт 1.

Будет гораздо красивей и, главное, правильней.
Будет время, попробую что-нибудь набросать
...
Рейтинг: 0 / 0
XSLT: Как сделать вывод таблицы в несколько столбцов
    #33815145
Виктор1111
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ух-ты! Спасибо за труды - попробую - только, чую я, не сразу так разберусь во всем:))
...
Рейтинг: 0 / 0
XSLT: Как сделать вывод таблицы в несколько столбцов
    #33815201
Виктор1111
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
О, сразу поправочка, могу конечно ошибаться и зря возмущаться:) - так как пока не совсем во все въехал - но у заголовка может тоже быть баннер - тогда выводится и залоговок, и под ним баннер - то есть как и обычно...
...
Рейтинг: 0 / 0
XSLT: Как сделать вывод таблицы в несколько столбцов
    #33815207
beard-electronic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Виктор1111О, сразу поправочка, могу конечно ошибаться и зря возмущаться:) - так как пока не совсем во все въехал - но у заголовка может тоже быть баннер - тогда выводится и залоговок, и под ним баннер - то есть как и обычно...
А как надо?
Как я понял - заголовок всегда в новой строке, если есть и баннер, то он идет как и все остальные - в данном случае в первой колонке новой строки.
...
Рейтинг: 0 / 0
XSLT: Как сделать вывод таблицы в несколько столбцов
    #33815235
Виктор1111
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
beard-electronic Виктор1111О, сразу поправочка, могу конечно ошибаться и зря возмущаться:) - так как пока не совсем во все въехал - но у заголовка может тоже быть баннер - тогда выводится и залоговок, и под ним баннер - то есть как и обычно...
А как надо?
Как я понял - заголовок всегда в новой строке, если есть и баннер, то он идет как и все остальные - в данном случае в первой колонке новой строки.

ага, так и есть! Наверно, я еще пока совсем мало понял из кода:)) Мудрено для меня пока, вроде отдельные вещи понятны, а в целом картины не вижу - надо глаз наметывать! Либо жара совсем голову расплавила...
...
Рейтинг: 0 / 0
XSLT: Как сделать вывод таблицы в несколько столбцов
    #33815275
beard-electronic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вобщем так:
Код: plaintext
1.
<xsl:variable name="structures" select="//s" />
В этой переменной содержатся все элементы с именем s (ведь в переменную можно класть и ноды, и коллекцию нод - node-set, а не только string, number...)
Далее - есть три шаблона по s - один общий, и два более конкретных -
для header и для баннеров (используются mode - используются для того,
чтоб один и тот же нод можно было обработать несколько раз с разным результатом).
Первый смотрит, что надо вызвать - если этот нод имеет header, то вызывает
c mode = header над собой же, иначе - с mode=banner.
Шаблон с mode = header выводит заголовок и вызывает banner над собой же (вдруг есть), причем передает в качестве параметра tablePos 1 - значит баннер будет первой ячейкой в строке. Еще не забываем закрыть TR, если уже выводили
ячейку с баннером (tablePos=1).
Баннер же смотрит - если баннер не пуст, то:
если ячейка 1-я (tablePos=1), выводим TR
сама ячейка
если ячейка 2-я - /TR
Далее вызываем шаблон без mode от следующего элемента, если есть, причем в
качестве номера следующей ячейки передаем 1, если было 2, и 2, если было 1 соответственно.

Вроде все ...
...
Рейтинг: 0 / 0
XSLT: Как сделать вывод таблицы в несколько столбцов
    #33815318
Виктор1111
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ну, вроде до меня оно доехало! Осталось только под мою более сложную структуру подогнать! Огромное спасибо!
...
Рейтинг: 0 / 0
22 сообщений из 22, страница 1 из 1
Форумы / XML, XSL, XPath, XQuery [игнор отключен] [закрыт для гостей] / XSLT: Как сделать вывод таблицы в несколько столбцов
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]