【问题标题】:xslt V1.0 - subtemplate with recursive loop returns empty valuexslt V1.0 - 带有递归循环的子模板返回空值
【发布时间】:2011-10-15 10:17:53
【问题描述】:

我正在尝试获取每个集群的子节点总和的最大值。

  • 集群 1:10 + 20 = 30

  • cluster2 : 20 + 30 = 50 --> 50 是最大值

问题:子模板的返回值为“”。
为什么?变量 tempMax 正在获取一个 node,其中包含我的号码,而不仅仅是一个号码。

$tempMax = {Dimension:[1]}
+ [1] = /
+ + node()[1] = 50

我该如何解决这个问题? (xslt v1.0)。


xml:

<?xml version="1.0"?>
<column-chart-stacked-full>
<clusters>
    <cluster number="1">
        <bar>
            <value>10</value>
        </bar>
        <bar>
            <value>20</value>
        </bar>
    </cluster>
    <cluster number="2">
        <bar>
            <value>20</value>
        </bar>
        <bar>
            <value>30</value>
        </bar>
    </cluster>
</clusters>
</column-chart-stacked-full>

我的 xsl:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <xsl:variable name="highestClusterVal">
        <xsl:call-template name="findMaxClusterVal"/>
    </xsl:variable>

    <xsl:template name="findMaxClusterVal">
        <xsl:param name="count" select="count(column-chart-stacked-  full/clusters/cluster)"/>
        <xsl:param name="limit" select="$count"/>
        <xsl:param name="max" select="0"/>
        <xsl:choose>
          <xsl:when test="$count &gt; 0">
            <xsl:variable name ="barSum" select="sum(column-chart-stacked-full/clusters/cluster[$count]/bar/value)"/>
            <xsl:variable name="tempMax">
              <xsl:choose>
                <xsl:when test="$max &lt; $barSum">
                  <xsl:value-of select="$barSum"/>
                </xsl:when>
                <xsl:otherwise>
                  <xsl:value-of select="$max"/>
                </xsl:otherwise>
              </xsl:choose>
            </xsl:variable>
            <!-- recursive loop -->
            <xsl:call-template name="findMaxClusterVal">
              <xsl:with-param name="count" select="$count - 1"/>
              <xsl:with-param name="limit" select="$limit"/>
              <xsl:with-param name="max" select="$tempMax"/>
            </xsl:call-template>
          </xsl:when>
          <xsl:otherwise>
            <!-- return max value -->
            <xsl:value-of select="$max"/>
         </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

</xsl:stylesheet>

$max 的回报

$max = {Dimension:[1]}
+ [1] = /
+ + node()[1] = 50

【问题讨论】:

    标签: c# .net xml xslt xslt-1.0


    【解决方案1】:

    您在分配tempMax 时缺少相反的情况:

            <xsl:variable name="tempMax">
                <xsl:if test="$max &lt; $barSum">
                    <xsl:value-of select="$barSum"/>
                </xsl:if>      
                <xsl:if test="$max >= $barSum">
                    <xsl:value-of select="$max"/>
                </xsl:if>
            </xsl:variable>
    

    这就是我测试它的方式(按照@Mads 的建议使用xsl:choose 进行了更改,即使在逻辑上是等效的)。

    [XSLT 1.0] 用 Saxon 6.5 测试

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output indent="yes"/>
    
        <xsl:template match="/">
            <xsl:call-template name="findMaxClusterVal"/>
        </xsl:template>
    
        <xsl:template name="findMaxClusterVal">
            <xsl:param name="count" select="count(column-chart-stacked-full/clusters/cluster)"/>
            <xsl:param name="limit" select="$count"/>
            <xsl:param name="max" select="0"/>
            <xsl:if test="$count &gt; 0">
                <xsl:variable name ="barSum" select="sum(column-chart-stacked-full/clusters/cluster[$count]/bar/value)"/>
                <xsl:variable name="tempMax">
                    <xsl:choose>
                        <xsl:when test="$max &lt; $barSum">
                            <xsl:value-of select="$barSum"/>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:value-of select="$max"/>
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:variable>
                <!-- recursive loop -->
                <xsl:call-template name="findMaxClusterVal">
                    <xsl:with-param name="count" select="$count - 1"/>
                    <xsl:with-param name="limit" select="$limit"/>
                    <xsl:with-param name="max" select="$tempMax"/>
                </xsl:call-template>
            </xsl:if>
            <!-- return max value -->
            <xsl:if test="$count = 0">
                <xsl:value-of select="$max"/>
            </xsl:if>
        </xsl:template>
    
    </xsl:stylesheet>
    

    应用于问题中提供的输入,返回50

    应用于此更改的输入:

    <column-chart-stacked-full>
        <clusters>
            <cluster number="1">
                <bar>
                    <value>10</value>
                </bar>
                <bar>
                    <value>20</value>
                </bar>
            </cluster>
            <cluster number="2">
                <bar>
                    <value>20</value>
                </bar>
                <bar>
                    <value>30</value>
                </bar>
            </cluster>
                    <cluster number="1">
                <bar>
                    <value>10</value>
                </bar>
                <bar>
                    <value>20</value>
                </bar>
            </cluster>
            <cluster number="2">
                <bar>
                    <value>70</value>
                </bar>
                <bar>
                    <value>30</value>
                </bar>
            </cluster>
        </clusters>
    </column-chart-stacked-full>
    

    返回100

    【讨论】:

    • +1 一个改进的想法:xsl:choose 可能比两个xsl:if 更合适。
    • 我再次调试了我的代码,$max 仍然返回节点而不是数值?
    • 这很奇怪。在给你答案之前,我已经执行了你的代码;它工作得很好。我会提供新的反馈。
    • 我尝试了另一个带有 saxon XSLT 处理器的调试器,它正在工作。我认为 .net XSLT 处理器正在解决数字到字符串更改的问题。当 tempMax 获得数值时,它会更改为字符串。
    • 使用大量的 number() 已经解决了这个问题 :)。感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-21
    • 2016-03-23
    • 2020-10-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多