Гость
Форумы / XML, XSL, XPath, XQuery [игнор отключен] [закрыт для гостей] / Игнорирование элементов-дубликатов / 9 сообщений из 9, страница 1 из 1
17.10.2012, 14:59
    #38002597
artwalek
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Игнорирование элементов-дубликатов
Есть такой xml

Код: xml
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.
<?xml version='1.0' standalone='yes'?>
<opt>
  <content>
    <category>
      <id>4</id>
      <description></description>
      <level>0</level>
      <title>Кафе</title>
    </category>
    <count>6</count>
    <items>
      <floor>1</floor>
      <item>
        <id>28</id>
        <description></description>
        <subtype>Кофейни</subtype>
        <title>Эспрессо-бар Милли</title>
        <type>Кафе</type>
      </item>
    </items>
    <items>
      <floor>0</floor>
      <item>
        <id>9</id>
        <description>&lt;h1&gt;Шоколадница&lt;/h1&gt;&lt;br/&gt;Тут описание &lt;b&gt;Шоколадница&lt;/b&gt;!!!!</description>
        <subtype>Кофейни</subtype>
        <title>Шоколадница</title>
        <type>Кафе</type>
      </item>
      <item>
        <id>10</id>
        <description></description>
        <subtype>Кофейни</subtype>
        <title>Джелато шоколадо</title>
        <type>Кафе</type>
      </item>
      <item>
        <id>11</id>
        <description>&lt;h1&gt;Пышка&lt;/h1&gt;&lt;br/&gt;Тут описание &lt;b&gt;Пышка&lt;/b&gt;!!!!</description>
        <subtype>Где поесть</subtype>
        <title>Пышка</title>
        <type>Кафе</type>
      </item>
    </items>
    <items>
      <floor>2</floor>
      <item>
        <id>63</id>
        <description></description>
        <subtype>Кофейни</subtype>
        <title>Coffe Shop</title>
        <type>Кафе</type>
      </item>
      <item>
        <id>62</id>
        <description></description>
        <subtype>Где поесть</subtype>
        <title>Пиццерия Мамма Миа</title>
        <type>Кафе</type>
      </item>
    </items>
  </content>
</opt>



Шаблон:
Код: xml
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.
<xsl:key name="key-category" match="item" use="subtype" />

<xsl:template match="content" name="cafes">
	<xsl:apply-templates select="items/item[generate-id(.)=generate-id(key('key-category', subtype))]" mode="item-cafe" />
</xsl:template>

<xsl:template match="item" mode="item-cafe">
	<div style="float: left; width: 50%;">
		<h3><xsl:value-of select="subtype" disable-output-escaping="yes" /></h3>
		<table>
			<xsl:apply-templates select="key('key-category', subtype)" mode="item-cafe-list">
				<xsl:sort select="../floor" order="descending" />
			</xsl:apply-templates>
		</table>
	</div>
</xsl:template>

<xsl:template match="item" mode="item-cafe-list">
	<tr>
		<td><xsl:if test="position()=1">уровень</xsl:if></td>
		<td>
			<xsl:for-each select="ancestor::items[not(floor=preceding-sibling::items/floor)]">
				<xsl:value-of select="floor" />
			</xsl:for-each>
		</td>
		<td><xsl:value-of select="title" disable-output-escaping="yes" /></td>
	</tr>
</xsl:template>



На выходе нужно получить
Кофейни
уровень
2 Coffe Shop
1 Эспрессо-бар Милли
0 Шоколадница
Джелато шоколадо

У меня же получается
Кофейни
уровень
2 Coffe Shop
1 Эспрессо-бар Милли
0 Шоколадница
0 Джелато шоколадо

Т. е. в конце 0 лишний (необходимо исключить дубликаты). Что я не так делаю?
...
Рейтинг: 0 / 0
17.10.2012, 16:11
    #38002792
mage.lan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Игнорирование элементов-дубликатов
artwalek,

Цикл этот зачем? Задачу конкретезировать надо было.
Код: xml
1.
2.
3.
<xsl:for-each select="ancestor::items[not(floor=preceding-sibling::items/floor)]">
	<xsl:value-of select="floor" />
</xsl:for-each>


Вероятно вас спасет если вы цикл вот в такую проверку запихнете:
Код: xml
1.
2.
<xsl:if test="preceding-sibling::*[position() = 1 and name()='floor']">
</xsl:if>
...
Рейтинг: 0 / 0
17.10.2012, 20:25
    #38003294
walek
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Игнорирование элементов-дубликатов
mage.lan
Цикл для исключения повторяющихся этажей, конкретно в этом случае должен быть 1 раз 0 этаж, вместо двух.
...
Рейтинг: 0 / 0
17.10.2012, 20:34
    #38003300
walek
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Игнорирование элементов-дубликатов
...
Рейтинг: 0 / 0
18.10.2012, 12:02
    #38003927
mage.lan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Игнорирование элементов-дубликатов
walek,

ну я получаю, то что на картинке, единственное, что я там минус поставил вместо распирающего дива

Код: xml
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.
<xsl:key name="key-category" match="item" use="subtype" />

<xsl:template match="content" name="cafes">
	<xsl:apply-templates select="items/item[generate-id(.)=generate-id(key('key-category', subtype))]" mode="item-cafe" />
</xsl:template>

<xsl:template match="item" mode="item-cafe">
	<div style="float: left; width: 50%;">
		<h3><xsl:value-of select="subtype" disable-output-escaping="yes" /></h3>
		<table>
			<xsl:apply-templates select="key('key-category', subtype)" mode="item-cafe-list">
				<xsl:sort select="../floor" order="descending" />
			</xsl:apply-templates>
		</table>
	</div>
</xsl:template>

<xsl:template match="item" mode="item-cafe-list">
	<tr>
		<td><xsl:if test="position()=1">уровень</xsl:if></td>
		<td>
			<xsl:choose>
				<xsl:when test="preceding-sibling::*[position() = 1 and name()='floor']">
					<xsl:value-of select="preceding-sibling::floor[1]" />
				</xsl:when>
				<xsl:otherwise>
					-
				</xsl:otherwise>
			</xsl:choose>
		</td>
		<td><xsl:value-of select="title" disable-output-escaping="yes" /></td>
	</tr>
</xsl:template>
...
Рейтинг: 0 / 0
18.10.2012, 12:55
    #38004028
artwalek
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Игнорирование элементов-дубликатов
mage.lan
Спасибо.
А почему position() = 1 and name()='floor' в предикате.
И ещё, картинка не полностью показана. Если посмотреть целиком на xml то там 2 таблицы, слева похожая, там тоже выводятся этажи, но в вашем шаблоне этажи не выводятся.
...
Рейтинг: 0 / 0
18.10.2012, 12:55
    #38004030
artwalek
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Игнорирование элементов-дубликатов
artwalekmage.lan
Спасибо.
А почему position() = 1 and name()='floor' в предикате.
И ещё, картинка не полностью показана. Если посмотреть целиком на xml то там 2 таблицы, слева похожая, там тоже выводятся этажи, но в вашем шаблоне этажи не выводятся.Прошу прощения, 2 таблица справа.
...
Рейтинг: 0 / 0
18.10.2012, 13:25
    #38004096
mage.lan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Игнорирование элементов-дубликатов
artwalek,

ну наконец-то я догнал, что вы хотите )))

Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
<xsl:template match="item" mode="item-cafe-list">
	<tr>
		<td><xsl:if test="position()=1">уровень</xsl:if></td>
		<td>
			<xsl:choose>
				<xsl:when test="preceding-sibling::*[position() = 1 and name()='floor'] or preceding-sibling::*[position() = 1 and name() = 'item' and subtype/text() != current()/subtype/text()]">
					<xsl:value-of select="preceding-sibling::floor[1]" />
				</xsl:when>
				<xsl:otherwise>
					-
				</xsl:otherwise>
			</xsl:choose>
		</td>
		<td><xsl:value-of select="title" disable-output-escaping="yes" /></td>
	</tr>
</xsl:template>



теперь по поводу проверки
preceding-sibling::*[position() = 1 and name()='floor']
берем всех обработанных на том же уровне, из них выбираем первого и у него должно быть имя тега floor (если в выборке никого, переходим к следующей части)
preceding-sibling::*[position() = 1 and name() = 'item' and subtype/text() != current()/subtype/text()
берем всех обработанных на том же уровне, из них выбираем первого и у него должно быть имя тега item а так же subtype не совпадать с subtype текущего тега,
если одно из условий верно, тогда надо строить floor

эту же проверку можно записать так, если она вам будет более понятна:
preceding-sibling::*[1][name()='floor'] or preceding-sibling::*[1][name() = 'item'][subtype/text() != current()/subtype/text()]
...
Рейтинг: 0 / 0
18.10.2012, 13:42
    #38004153
artwalek
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Игнорирование элементов-дубликатов
mage.lan

Спасибо, всё получилось
Путь конечно довольно сложный. Я прямолинейно рассуждал.
...
Рейтинг: 0 / 0
Форумы / XML, XSL, XPath, XQuery [игнор отключен] [закрыт для гостей] / Игнорирование элементов-дубликатов / 9 сообщений из 9, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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