Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / XML, XSL, XPath, XQuery [игнор отключен] [закрыт для гостей] / Группировка элементов с одноразовым выводом повторяющихся / 5 сообщений из 5, страница 1 из 1
12.05.2008, 16:57
    #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
12.05.2008, 18:30
    #35307362
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Группировка элементов с одноразовым выводом повторяющихся
http://xmlhack.ru/forum/xml/topic4537.html
Соответственно вместо count() использовать sum()

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

С уважением, Vasilisk
...
Рейтинг: 0 / 0
13.05.2008, 13:05
    #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
Форумы / XML, XSL, XPath, XQuery [игнор отключен] [закрыт для гостей] / Группировка элементов с одноразовым выводом повторяющихся / 5 сообщений из 5, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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