powered by simpleCommunicator - 2.0.50     © 2025 Programmizd 02
Форумы / XML, XSL, XPath, XQuery [игнор отключен] [закрыт для гостей] / Игнорирование элементов-дубликатов
9 сообщений из 9, страница 1 из 1
Игнорирование элементов-дубликатов
    #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
Игнорирование элементов-дубликатов
    #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
Игнорирование элементов-дубликатов
    #38003294
walek
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
mage.lan
Цикл для исключения повторяющихся этажей, конкретно в этом случае должен быть 1 раз 0 этаж, вместо двух.
...
Рейтинг: 0 / 0
Игнорирование элементов-дубликатов
    #38003300
walek
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
...
Рейтинг: 0 / 0
Игнорирование элементов-дубликатов
    #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
Игнорирование элементов-дубликатов
    #38004028
artwalek
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
mage.lan
Спасибо.
А почему position() = 1 and name()='floor' в предикате.
И ещё, картинка не полностью показана. Если посмотреть целиком на xml то там 2 таблицы, слева похожая, там тоже выводятся этажи, но в вашем шаблоне этажи не выводятся.
...
Рейтинг: 0 / 0
Игнорирование элементов-дубликатов
    #38004030
artwalek
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
artwalekmage.lan
Спасибо.
А почему position() = 1 and name()='floor' в предикате.
И ещё, картинка не полностью показана. Если посмотреть целиком на xml то там 2 таблицы, слева похожая, там тоже выводятся этажи, но в вашем шаблоне этажи не выводятся.Прошу прощения, 2 таблица справа.
...
Рейтинг: 0 / 0
Игнорирование элементов-дубликатов
    #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
Игнорирование элементов-дубликатов
    #38004153
artwalek
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
mage.lan

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


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