Использование max в переменной в XSLT 1.0 - PullRequest
2 голосов
/ 21 марта 2011

можно ли использовать функцию max в переменной в XSLT 1?Мне нужно найти максимальное значение внутри некоторых узлов, и мне нужно будет вызывать это из большего количества мест.Поэтому я попытался создать шаблон:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:msxsl="urn:schemas-microsoft-com:xslt"
 xmlns:essox="urn:essox-scripts">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:template name="Field001_max_dluznych_splatek">
        <xsl:param name="CrRep"/>
        <xsl:variable name="PocetDluznychSplatekSplatky">
            <xsl:value-of
             select="max($CrRep
                         /Response
                          /ContractData
                           /Installments
                            /InstDetail
                             /NrOfDueInstalments)" />
        </xsl:variable>
        <xsl:variable name="PocetDluznychSplatekKarty">
            <xsl:value-of
             select="max($CrRep
                          /Response
                           /ContractData
                            /Cards
                             /CardDetail
                              /NrOfDueInstalments)" />
        </xsl:variable>
        <xsl:choose>
            <xsl:when test="$PocetDluznychSplatekSplatky
                             &gt;= $PocetDluznychSplatekKarty">
                <xsl:value-of select="$PocetDluznychSplatekSplatky"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$PocetDluznychSplatekKarty"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

В XML Spy я получаю эту ошибку:

Error in XPath expression Unknown function - Name and number of arguments do not match any function signature in the static context - 'max'.

Что не так?Большое спасибо, Питер

Ответы [ 2 ]

3 голосов
/ 21 марта 2011

Используйте хорошо известную максимальную идиому:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:msxsl="urn:schemas-microsoft-com:xslt"
 xmlns:essox="urn:essox-scripts">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:template name="Field001_max_dluznych_splatek">
        <xsl:param name="CrRep"/>
        <xsl:variable name="PocetDluznychSplatekSplatky">
            <xsl:call-template name="maximun">
                <xsl:with-param name="pSequence"
                 select="$CrRep
                          /Response
                           /ContractData
                            /Installments
                             /InstDetail
                              /NrOfDueInstalments"/>
            </xsl:call-template>
        </xsl:variable>
        <xsl:variable name="PocetDluznychSplatekSplatky">
            <xsl:call-template name="maximun">
                <xsl:with-param name="pSequence"
                 select="$CrRep
                          /Response
                           /ContractData
                            /Cards
                             /CardDetail
                              /NrOfDueInstalments"/>
            </xsl:call-template>
        </xsl:variable>
        <xsl:choose>
            <xsl:when test="$PocetDluznychSplatekSplatky
                             &gt;= $PocetDluznychSplatekKarty">
                <xsl:value-of select="$PocetDluznychSplatekSplatky"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$PocetDluznychSplatekKarty"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    <xsl:template name="maximun">
        <xsl:param name="pSequence"/>
        <xsl:for-each select="$pSequence">
            <xsl:sort select="." data-type="number" order="descending"/>
            <xsl:if test="position()=1">
                <xsl:value-of select="."/>
            </xsl:if>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

Примечание : в именованном шаблоне для повторного использования.

1 голос
/ 21 марта 2011

В XSLT 1.0 нет функции max. Вы можете обойти это, отсортировав элементы по убыванию, а затем приняв значение первого.

Вот еще один (более медленный) способ сделать это:

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:variable name="PocetDluznychSplatekSplatky"
        select="/test/PocetDluznychSplatekSplatky/val[not(../val &gt; .)][1]" />
    <xsl:variable name="PocetDluznychSplatekKarty"
        select="/test/PocetDluznychSplatekKarty/val[not(../val &gt; .)][1]" />
    <xsl:template match="/">
        <xsl:choose>
            <xsl:when
                test="$PocetDluznychSplatekSplatky &gt;= 
                      $PocetDluznychSplatekKarty">
                <xsl:value-of select="$PocetDluznychSplatekSplatky" />
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$PocetDluznychSplatekKarty" />
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

Пример исходного документа:

<test>
    <PocetDluznychSplatekSplatky>
        <val>22</val>
        <val>3241</val>
        <val>13</val>
    </PocetDluznychSplatekSplatky>
    <PocetDluznychSplatekKarty>
        <val>1</val>
        <val>3234341</val>
        <val>13</val>
    </PocetDluznychSplatekKarty>
</test>

Выход:

3234341

XPath в каждой переменной select выглядит следующим образом:

/test/PocetDluznychSplatekSplatky/val[not(../val &gt; .)][1]

Или выберите элемент val, не имеющий братьев или сестер val, с большим значением (т. Е. Максимальным).

(Очевидно, вам нужно настроить XPath в соответствии с вашим исходным документом.)

Примечание: Решение sort работает намного лучше (при условии реализации сортировки n*log(n)). Второй подход должен сравнивать каждый val с каждым из его братьев и сестер и поэтому является квадратичным.

...