xslt空标签检查

时间:2013-06-21 07:18:51

标签: xml xslt saxon

我有以下结构:

<?xml version="1.0" encoding="UTF-8"?>
<Legs>
  <Leg>
    <LegNo>1</LegNo>
    <RaceInfo>
      <RaceNo>1</RaceNo>
      <Name/>
      <BaseDistance>2140</BaseDistance>
      <StartMethod Code="A"/>
      <StartTime>
        <Hour>13</Hour>
        <Minute>48</Minute>
      </StartTime>
      <Status>OpenForSell</Status>
      <NumberOfStarts>10</NumberOfStarts>
    </RaceInfo>
    <Starts>
      <Start>
        <StartNo>1</StartNo>
        <Horse>
          <RegNo>578001020080423</RegNo>
          <Name>Mino</Name>
        </Horse>
        <Driver>
          <LicenseNo>29749</LicenseNo>
          <FirstName>Hovel</FirstName>
          <LastName>Helmen</LastName>
        </Driver>
        <Distance>2140</Distance>
        <Scratched>false</Scratched>
        <Ranking>2</Ranking>
      </Start>
      <Start>
        <StartNo>2</StartNo>
        <Horse>
          <RegNo>578001020080121</RegNo>
          <Name>Furderud Svarten</Name>
        </Horse>
        <Driver>
          <LicenseNo>4290</LicenseNo>
          <FirstName>Bjørn</FirstName>
          <LastName>Humborstad</LastName>
        </Driver>
        <Distance>2140</Distance>
        <Scratched>false</Scratched>
        <Ranking/>
      </Start>
    </Starts>
  </Leg>
</Legs>

我正在使用此代码的一部分转换为XML:

<?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">
<p class="txt">
            <xsl:text>Rangering: </xsl:text>
            <xsl:variable name="found">
                <xsl:text>false</xsl:text>
            </xsl:variable>
            <xsl:for-each select="Legs[@ResultsComplete='true']/Leg">

                <xsl:value-of select="LegNo" />
                <xsl:text>. avd: </xsl:text>

                <xsl:call-template name="getRanking">
                    <xsl:with-param name="structure" select="Starts" />
                    <xsl:with-param name="counter" select="1" />
                    <xsl:with-param name="winner" select="Winners/Winner/@StartNo" />

                </xsl:call-template>

                <xsl:choose>
                    <xsl:when test="Starts/Start/Scratched = 'true'">
                        <xsl:text> (str. </xsl:text>
                        <xsl:for-each select="Starts/Start[Ranking=0]/StartNo">
                            <xsl:value-of select="." />
                            <xsl:choose>
                                <xsl:when test="position() = last()">
                                    <xsl:text>)</xsl:text>
                                </xsl:when>
                                <xsl:otherwise>
                                    <xsl:text>, </xsl:text>
                                </xsl:otherwise>
                            </xsl:choose>
                        </xsl:for-each>
                    </xsl:when>
                </xsl:choose>

                <xsl:choose>
                    <xsl:when test="position() = last()">
                        <xsl:text>.</xsl:text>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:text>, </xsl:text>
                    </xsl:otherwise>
                </xsl:choose>

            </xsl:for-each>
        </p>
    <xsl:template name="getRanking">
        <xsl:param name="structure"/>
        <xsl:param name="counter"/>
        <xsl:param name="winner"/>

        <xsl:choose>
            <xsl:when test="$structure/Start[Ranking=$counter]/StartNo = $winner">
                <xsl:value-of select="$structure/Start[Ranking=$counter]/StartNo"/>
                <!--<xsl:text> </xsl:text>-->
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$structure/Start[Ranking=$counter]/StartNo"/>
                <xsl:text>-</xsl:text>
                <xsl:call-template name="getRanking">
                    <xsl:with-param name="structure" select="$structure"/>
                    <xsl:with-param name="counter" select="$counter + 1"/>
                    <xsl:with-param name="winner" select="$winner"/>
                </xsl:call-template>
            </xsl:otherwise>
        </xsl:choose>

    </xsl:template>

</xsl:stylesheet>

输出应为逗号分隔的数字列表。 怎么样当我点击空标签时,我收到'FORG0001: Cannot convert string to double'错误。

我使用的是Saxon 9.4.0.6。

我曾尝试在choose-block之前添加if语句,但这似乎并不重要。

我想要实现的是跳过具有空排名元素的块。

这是所需的输出(当我没有空的排名元素时,它会起作用:

<p class="txt">Rangering: 1. avd: 7 (str. 2, 6), 2. avd: 5, 3. avd: 1-6, 4. avd: 1-11 (str. 3, 6, 8, 12), 5. avd: 2-12-6 (str. 4, 5, 10).</p>

1 个答案:

答案 0 :(得分:0)

当您最初调用 getRanking 模板时,而不是这样做...

<xsl:with-param name="structure" select="Starts" />

尝试这样做,过滤掉没有排名的开始元素

<xsl:with-param name="structure" select="Starts/Start[Ranking != '']" />

由于结构元素不再包含 Starts 元素,因此您还必须简化 getRanking 元素中的表达式,如下所示:< / p>

    <xsl:choose>
        <xsl:when test="$structure[Ranking=$counter]/StartNo = $winner">
          <xsl:value-of select="$structure[Ranking=$counter]/StartNo"/>

说了这么多,我想知道你是否可以简化整个逻辑,只需在这里使用 xsl:for-each 循环,而不是递归调用模板......

<xsl:for-each select="Starts/Start[Ranking != '']">
   <xsl:sort select="Ranking" />
   <!-- existing code from getRanking template -->

如果你想在找到胜利者时“中止”循环,你可以按如下方式构建它

<xsl:variable name="winnerRanking" select="Starts/Start[StartNo = $winner]/Ranking" />
<xsl:for-each select="Starts/Start[Ranking != ''][Ranking &lt;= $winnerRanking]">
   <xsl:sort select="Ranking" />