powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / XML, XSL, XPath, XQuery [игнор отключен] [закрыт для гостей] / Группировка элементов с одноразовым выводом повторяющихся
5 сообщений из 5, страница 1 из 1
Группировка элементов с одноразовым выводом повторяющихся
    #35307094
Avenger_by
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Привет всем, у меня такой вопрос:
Есть xml:
Код: 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.
<?xml version="1.0" encoding="UTF-8"?>
<goods>
	<item class="fruit">apple</item>
	<quantity> 21 </quantity>
	<cost> 21 </cost>
	
	<item class="fruit">pineapple</item>
	<quantity> 11 </quantity>
	<cost> 101 </cost>
	
	<item class="fruit">grape</item>
	<quantity> 25 </quantity>
	<cost> 30 </cost>
	
	<item class="fruit">grape</item>
	<quantity> 40 </quantity>
	<cost> 20 </cost>
	
	<item class="fruit">apple</item>
	<quantity> 14 </quantity>
	<cost> 28 </cost>
	
	<item class="fruit">pear</item>
	<quantity> 17 </quantity>
	<cost> 20 </cost>
	
	<item class="fruit">banana</item>
	<quantity> 50 </quantity>
	<cost> 22 </cost>
</goods>
нужно представить его в таком виде:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
<fruits>
    <item id="apple">
        <quantity> 35 </quantity>
        <cost> 49 </cost>
    </item>
    <item id="pineapple">
        <quantity> 11 </quantity>
        <cost> 101 </cost>
    </item>
</fruits>
и т.д. То есть нужно вывести в новом виде, а те item которые повторяются просуммировать их значения quantity и cost и вывести эту сумму вместе с остальными в таком же виде.
появилась идея создать шаблон и изменить там структуру входящего xml и записать это в переменную так, чтобы можно было использовать ключи, сделал вот так:
Код: 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.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
	<xsl:element name="All">
	    <xsl:apply-templates select="goods/item"/>
	</xsl:element>
    </xsl:template>
    <xsl:template match="item">
	<xsl:variable name="parsed">
	    <xsl:call-template name="structure"/>
	</xsl:variable>
        <xsl:for-each select="$parsed">
	    <item>
	        <xsl:attribute name="id"><xsl:value-of select="$parsed/item/@name"/></xsl:attribute>
		<quantity><xsl:value-of select="$parsed/item/@quantity"/></quantity>
		<cost><xsl:value-of select="$parsed/item/@cost"/></cost>
	    </item>
	</xsl:for-each> 
    </xsl:template>
    <xsl:template name="structure">
	<item>
	    <xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
	    <xsl:attribute name="name"><xsl:value-of select="."/></xsl:attribute>
	    <xsl:attribute name="quantity"><xsl:value-of select="following-sibling::quantity"/></xsl:attribute>
	    <xsl:attribute name="cost"><xsl:value-of select="following-sibling::cost"/></xsl:attribute>
	</item>
    </xsl:template>
</xsl:stylesheet>
после этого в переменной $parsed содержится xml структура такого вида:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
<All>
	<item class="fruit" name="apple" quantity="21" cost="21" />
	<item class="fruit" name="pineapple" quantity="11" cost="101" />
	<item class="fruit" name="grape" quantity="25" cost="30" />
	<item class="fruit" name="grape" quantity="40" cost="20" />
	<item class="fruit" name="apple" quantity="14" cost="28" />
	<item class="fruit" name="pear" quantity="17" cost="20" />
	<item class="fruit" name="banana" quantity="50" cost="22" />
</All>
и на выходе я получаю результат в нужном виде, но без суммирования повторяющихся:
Код: 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.
<All>
	<item id="apple">
		<quantity> 21 </quantity>
		<cost> 21 </cost>
	</item>
	<item id="pineapple">
		<quantity> 11 </quantity>
		<cost> 101 </cost>
	</item>
	<item id="grape">
		<quantity> 25 </quantity>
		<cost> 30 </cost>
	</item>
	<item id="grape">
		<quantity> 40 </quantity>
		<cost> 20 </cost>
	</item>
	<item id="apple">
		<quantity> 14 </quantity>
		<cost> 28 </cost>
	</item>
	<item id="pear">
		<quantity> 17 </quantity>
		<cost> 20 </cost>
	</item>
	<item id="banana">
		<quantity> 50 </quantity>
		<cost> 22 </cost>
	</item>
</All>
помогите пожалуйста с суммированием, хотел через xsl:key делать, но ведь match в нем не может содержать переменных, а у меня структура, которую можно использовать с xsl:key содержится в переменной. или может есть какие то другие пути решения? извиняюсь что так много кода. спасибо заранее.
...
Рейтинг: 0 / 0
Группировка элементов с одноразовым выводом повторяющихся
    #35307362
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
http://xmlhack.ru/forum/xml/topic4537.html
Соответственно вместо count() использовать sum()

С уважением, Vasilisk
...
Рейтинг: 0 / 0
Группировка элементов с одноразовым выводом повторяющихся
    #35307411
Avenger_by
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
а через xsl:key есть решение?
...
Рейтинг: 0 / 0
Группировка элементов с одноразовым выводом повторяющихся
    #35307561
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не знаю. Я всегда использовал preceding-sibling

С уважением, Vasilisk
...
Рейтинг: 0 / 0
Группировка элементов с одноразовым выводом повторяющихся
    #35308678
Volder
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
получилось так, совсем без переменных:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:template match="/goods">
		<all>
			<xsl:for-each select="item">
				<xsl:sort/>
				<xsl:if test="concat(following-sibling::item[text()=current()],1)=1">
					<item>
						<xsl:attribute name="id"><xsl:value-of select="."/></xsl:attribute>
						<quantity>
							<xsl:value-of select="sum(../item[text()=current()]/following-sibling::quantity[1])"/>
						</quantity>
						<cost>
							<xsl:value-of select="sum(../item[text()=current()]/following-sibling::cost[1])"/>
						</cost>
					</item>
				</xsl:if>
			</xsl:for-each>
		</all>
	</xsl:template>
</xsl:stylesheet>

в результате получается, то, что нужно:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
<?xml version="1.0" encoding="UTF-8"?>
<all>
	<item id="apple">
		<quantity> 35 </quantity>
		<cost> 49 </cost>
	</item>
	<item id="banana">
		<quantity> 50 </quantity>
		<cost> 22 </cost>
	</item>
	<item id="grape">
		<quantity> 65 </quantity>
		<cost> 50 </cost>
	</item>
	<item id="pear">
		<quantity> 17 </quantity>
		<cost> 20 </cost>
	</item>
	<item id="pineapple">
		<quantity> 11 </quantity>
		<cost> 101 </cost>
	</item>
</all>
подскажите, как можно по-другому обрабатывать пустые значения? вместо
Код: plaintext
<xsl:if test="concat(following-sibling::item[text()=current()],1)=1">
...
Рейтинг: 0 / 0
5 сообщений из 5, страница 1 из 1
Форумы / XML, XSL, XPath, XQuery [игнор отключен] [закрыт для гостей] / Группировка элементов с одноразовым выводом повторяющихся
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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