powered by simpleCommunicator - 2.0.48     © 2025 Programmizd 02
Форумы / XML, XSL, XPath, XQuery [игнор отключен] [закрыт для гостей] / Сумма непустых элементов в рекурсии
8 сообщений из 8, страница 1 из 1
Сумма непустых элементов в рекурсии
    #39441636
adar7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Используется XSLT 1.0. есть XML:
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
<root>
<SUM_1>10<SUM_1>
<SUM_2>7<SUM_2>
<SUM_5><SUM_5>
<SUM_6>3<SUM_6>
<SUM_11>1<SUM_11>
<SUM_15>12<SUM_15>
<root>


Всего элементов SUM_<N> может быть 15. Могут присутствовать все, могут отсутствовать некоторые, некоторые могут быть пустыми.
Нужно посчитать сумму всех элементов. Знаю, что решается задача c помощью рекурсии, но дальнейшие продвижения по этой теме результата не дали. Помогите, пожалуйста.
...
Рейтинг: 0 / 0
Сумма непустых элементов в рекурсии
    #39441638
adar7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
adar7,

извиняюсь, XML такой:
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
<root>
<SUM_1>10</SUM_1>
<SUM_2>7</SUM_2>
<SUM_5></SUM_5>
<SUM_6>3</SUM_6>
<SUM_11>1</SUM_11>
<SUM_15>12</SUM_15>
</root>
...
Рейтинг: 0 / 0
Сумма непустых элементов в рекурсии
    #39441640
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: xml
1.
2.
3.
<xsl:template match="root">
  <xsl:value-of select="sum(*)"/>
</xsl:template>
...
Рейтинг: 0 / 0
Сумма непустых элементов в рекурсии
    #39441666
adar7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

спасибо, но реальный ХМL содержит другие элементы, где тоже есть числа. Хочется выбрать только элементы вида SUM_<N>.


Код: 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.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
    <xsl:output method="xml" version="1.0" encoding="utf-8" omit-xml-declaration="yes" indent="yes"/> 
    <xsl:template match="/">
        <root>  
            <xsl:element name="eps">
                <xsl:attribute name="name">NAZN.TOTAL_SUM</xsl:attribute>
                <xsl:variable name="total_sum">
                    <xsl:call-template name="sumParam">
                        <xsl:with-param name="count_service" select="15"/>
                    </xsl:call-template>
                </xsl:variable>                
                <xsl:call-template name="format_number">
                    <xsl:with-param name="number" select="$total_sum"/>
                </xsl:call-template>
           </xsl:element>
        </root>
    </xsl:template>
    <xsl:template name="format_number">
        <xsl:param name="number"/>
        <xsl:choose>
            <xsl:when test="not (normalize-space($number)) or string($number)='NaN'">
                <xsl:value-of select="'0.00'"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="format-number(translate($number, ',', '.'), '0.00')"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    <xsl:template name="sumParam">
        <xsl:param name="count_service"/>
        <xsl:param name="pAccum" select="0"/>        
        <xsl:choose>
            <xsl:when test="number($count_service) > 0">              
                <xsl:call-template name="sumParam">
                    <xsl:with-param name="count_service" select="$count_service - 1"/>
                    <xsl:with-param name="pAccum" select="$pAccum+ number(concat('/SUM_',$count_service))"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$pAccum"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>



результат:
Код: xml
1.
2.
3.
<root>
   <eps name="NAZN.TOTAL_SUM">0.00</eps>
</root>
...
Рейтинг: 0 / 0
Сумма непустых элементов в рекурсии
    #39442003
adar7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
adar7,

в общем собрал решение, может кому пригодиться, но оно некрасивое с дублированием кода и без динамического вызова тегов <SUM_[N]>.
Код: 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.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
    <xsl:output method="xml" version="1.0" encoding="utf-8" omit-xml-declaration="yes" indent="yes"/> 
    <xsl:template match="/">
        <root>  
            <xsl:element name="eps">
                <xsl:attribute name="name">NAZN.TOTAL_SUM</xsl:attribute>
                <xsl:variable name="total_sum">
                    <xsl:call-template name="sumParam">
                        <xsl:with-param name="count_service" select="15"/>
                    </xsl:call-template>
                </xsl:variable>    
                <xsl:call-template name="format_number">
                    <xsl:with-param name="number" select="$total_sum"/>
                </xsl:call-template>
            </xsl:element>
        </root>
    </xsl:template>
    <xsl:template name="format_number">
        <xsl:param name="number"/>
        <xsl:choose>
            <xsl:when test="not (normalize-space($number)) or string($number)='NaN'">
                <xsl:value-of select="'0.00'"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="format-number(translate($number, ',', '.'), '0.00')"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    <xsl:template name="sumParam">
        <xsl:param name="count_service"/>
        <xsl:param name="pAccum" select="0"/>        
        <xsl:choose>
            <xsl:when test="number($count_service) &gt; 0">   
                <xsl:variable name="value">
                <xsl:choose>
                    <xsl:when test="$count_service = 1"><xsl:value-of select="//SUM_1"/></xsl:when>
                    <xsl:when test="$count_service = 2"><xsl:value-of select="//SUM_2"/></xsl:when>
                    <xsl:when test="$count_service = 3"><xsl:value-of select="//SUM_3"/></xsl:when>
                    <xsl:when test="$count_service = 4"><xsl:value-of select="//SUM_4"/></xsl:when>
                    <xsl:when test="$count_service = 5"><xsl:value-of select="//SUM_5"/></xsl:when>
                    <xsl:when test="$count_service = 6"><xsl:value-of select="//SUM_6"/></xsl:when>
                    <xsl:when test="$count_service = 7"><xsl:value-of select="//SUM_7"/></xsl:when>
                    <xsl:when test="$count_service = 8"><xsl:value-of select="//SUM_8"/></xsl:when>
                    <xsl:when test="$count_service = 9"><xsl:value-of select="//SUM_9"/></xsl:when>
                    <xsl:when test="$count_service = 10"><xsl:value-of select="//SUM_10"/></xsl:when>
                    <xsl:when test="$count_service = 11"><xsl:value-of select="//SUM_11"/></xsl:when>
                    <xsl:when test="$count_service = 12"><xsl:value-of select="//SUM_12"/></xsl:when>
                    <xsl:when test="$count_service = 13"><xsl:value-of select="//SUM_13"/></xsl:when>
                    <xsl:when test="$count_service = 14"><xsl:value-of select="//SUM_14"/></xsl:when>
                    <xsl:when test="$count_service = 15"><xsl:value-of select="//SUM_15"/></xsl:when>
                </xsl:choose>    
                </xsl:variable>
                <xsl:variable name="value_norm">
                <xsl:choose>
                    <xsl:when test="not (normalize-space($value)) or string($value)='NaN'">
                        <xsl:value-of select="'0.00'"/>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:value-of select="format-number(translate($value, ',', '.'), '0.00')"/>
                    </xsl:otherwise>
                </xsl:choose>
                </xsl:variable>
                <xsl:variable name="cnt"><xsl:value-of select="concat('//SUM_',$count_service)"/></xsl:variable>
                <xsl:variable name="cnt2"><xsl:value-of select="$cnt"/></xsl:variable>
                <xsl:call-template name="sumParam">
                    <xsl:with-param name="count_service" select="$count_service - 1"/>
                    <xsl:with-param name="pAccum" select="$pAccum+$value_norm"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$pAccum"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>   
</xsl:stylesheet>
...
Рейтинг: 0 / 0
Сумма непустых элементов в рекурсии
    #39442277
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
adar7Хочется выбрать только элементы вида SUM_<N>.
Код: xml
1.
2.
3.
<xsl:template match="root">
  <xsl:value-of select="sum(*[starts-with(name(), 'SUM_')])"/>
</xsl:template>
...
Рейтинг: 0 / 0
Сумма непустых элементов в рекурсии
    #39452089
adar7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

поправленьице
Код: xml
1.
2.
3.
<xsl:template match="root">
<xsl:value-of select="format-number(sum(//*[starts-with(name(), 'SUM_')]),'0.00')"/>
</xsl:template>
...
Рейтинг: 0 / 0
Сумма непустых элементов в рекурсии
    #39452313
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
adar7поправленьице НИКОГДА не используйте оператор // Он заставляет просматривать ВЕСЬ XML
...
Рейтинг: 0 / 0
8 сообщений из 8, страница 1 из 1
Форумы / XML, XSL, XPath, XQuery [игнор отключен] [закрыт для гостей] / Сумма непустых элементов в рекурсии
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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