尽管返回了False,

时间:2019-10-23 11:59:46

标签: xslt xslt-2.0

我正在使用迭代模板来总计一些元素,而我看不到更干净的管理方法。但是,尽管初始if语句的评估结果为false,嵌套的if也会被评估。

此代码段并不优雅,但显示了我正在处理的内容。测试变量应返回一个数字,但返回一个空值。我已经使用调试器跟踪了变量,直到最后一次评估(即当typeCount大于typeTotal时)一切都很好。此时,正在评估position()= typeCount并重置rowCount。

据我所知,如果第一个If失败,则没有理由对第二个If进行评估。因此,最后一次迭代生成的结果应返回到测试变量。

我正在使用Saxon-PE 9.7.0.19处理器在OxygenML中运行此程序

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0">
    <xsl:output encoding="UTF-8" method="text"/>

    <xsl:variable name="contractTypeCount" select="count(distinct-values(costDefinitions/cost/contract/contractType/@printcode))"/>

    <xsl:template match="/">
        <xsl:variable name="test">
            <xsl:call-template name="typeGrouping">
                <xsl:with-param name="rowCount" select="0"/>
                <xsl:with-param name="typeCount" select="1"/>
                <xsl:with-param name="typeTotal" select="$contractTypeCount"/>
            </xsl:call-template>
        </xsl:variable>

       <xsl:value-of select="concat('Count:',$test)"/>
    </xsl:template>


    <xsl:template name="typeGrouping">
        <xsl:param name="typeCount"/>
        <xsl:param name="rowCount"/>
        <xsl:param name="typeTotal"/>

        <xsl:if test="$typeCount &lt;= $typeTotal">
            <xsl:for-each-group select="/costDefinitions/cost/contract/contractType" group-by="@printcode">
                <xsl:sort select="@printcode" data-type="text" order="ascending"/>
                <xsl:if test="position() = $typeCount">
                    <xsl:variable name="typeTemp" select="@printcode"/>
                    <xsl:variable name="countTemp" select="count(distinct-values(/costDefinitions/cost[contract/contractType/@printcode = $typeTemp]/creditor/@printcode))"/>
                    <xsl:call-template name="typeGrouping">
                        <xsl:with-param name="typeCount" select="$typeCount + 1"/>
                        <xsl:with-param name="rowCount" select="$rowCount + $countTemp"/>
                        <xsl:with-param name="typeTotal" select="$typeTotal"/>
                    </xsl:call-template>
                </xsl:if>
            </xsl:for-each-group>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

使用此XML代码段,我期望返回值为5:Purchase = 3 and Barter = 2。

<?xml version="1.0" encoding = "UTF-8"?>
<costDefinitions>
    <cost>
        <contract>
            <contractType printcode="Purchase"/>
        </contract>
        <creditor printcode="ABCD"/>
    </cost>
    <cost>
        <contract>
            <contractType printcode="Purchase"/>
        </contract>
        <creditor printcode="ABCD"/>
    </cost>
    <cost>
        <contract>
            <contractType printcode="Barter"/>
        </contract>
        <creditor printcode="ABCD"/>
    </cost>
    <cost>
        <contract>
            <contractType printcode="Purchase"/>
        </contract>
        <creditor printcode="ABCD"/>
    </cost>
    <cost>
        <contract>
            <contractType printcode="Purchase"/>
        </contract>
        <creditor printcode="KMNO"/>
    </cost>
    <cost>
        <contract>
            <contractType printcode="Barter"/>
        </contract>
        <creditor printcode="KMNO"/>
    </cost>
    <cost>
        <contract>
            <contractType printcode="Purchase"/>
        </contract>
        <creditor printcode="KMNO"/>
    </cost>
    <cost>
        <contract>
            <contractType printcode="Purchase"/>
        </contract>
        <creditor printcode="KMNO"/>
    </cost>
    <cost>
        <contract>
            <contractType printcode="Purchase"/>
        </contract>
        <creditor printcode="STUV"/>
    </cost>
    <cost>
        <contract>
            <contractType printcode="Purchase"/>
        </contract>
        <creditor printcode="STUV"/>
    </cost>
</costDefinitions>

1 个答案:

答案 0 :(得分:1)

我并没有真正研究为什么您的XSLT没有给您想要的结果,因为实际上有一种更简单的方法来做到这一点。您可以像这样获得非重复计数:

 <xsl:variable name="contractTypeCount" 
               select="count(distinct-values(costDefinitions/cost/concat(contract/contractType/@printcode, '|', creditor/@printcode)))"/>

因此,此变量应根据需要包含“ 5”。