XSLT:使用键和条件的“选择值”?

问题描述 投票:0回答:2

这个问题是上一个线程的延续:XSLT:根据其他节点的值之和进行排序

我现在可以使用键从其他节点求和数据。 我似乎无法得到的是现在应用条件来选择使用这些键时所需要的数据所需的语法或方法。

这是我正在使用的简化 xml(对上一个进行了修改以突出显示问题):

<Horses>
    <Horse>
        <ID>1</ID>
        <Name>hrsA</Name>
        <SireID>101</SireID>
        <Age>3</Age>
        <Pace>
            <Stakes>20</Stakes>
            <Wins>0</Wins>
        </Pace>
    </Horse>
    <Horse>
        <ID>2</ID>
        <Name>hrsB</Name>
        <SireID>101</SireID>
        <Age>6</Age>
        <Pace>
            <Stakes>1600</Stakes>
            <Wins>9</Wins>
        </Pace>
    </Horse>
    <Horse>
        <ID>3</ID>
        <Name>hrsC</Name>
        <SireID>101</SireID>
        <Age>3</Age>
        <Trot>
            <Stakes>200</Stakes>
            <Wins>2</Wins>
        </Trot>
    </Horse>
    <Horse>
        <ID>4</ID>
        <Name>hrsD</Name>
        <SireID>101</SireID>
        <Age>4</Age>
        <Pace>
            <Stakes>50</Stakes>
            <Wins>0</Wins>
        </Pace>
        <Trot>
            <Stakes>100</Stakes>
            <Wins>1</Wins>
        </Trot>
    </Horse>
    <Horse>
        <ID>5</ID>
        <Name>hrsE</Name>
        <SireID>101</SireID>
        <Age>3</Age>
        <Pace>
            <Stakes>100</Stakes>
            <Wins>1</Wins>
        </Pace>
        <Trot>
            <Stakes>300</Stakes>
            <Wins>1</Wins>
        </Trot>
    </Horse>
</Horses>
<Sires>
    <Sire>
        <ID>101</ID>
        <Name>srA</Name>
        <LiveFoalsALL>117</LiveFoalsALL>
    </Sire>
</Sires>

在一种情况下,我需要获得属于一位父亲且达到一定年龄的后代(马)。

在没有指定年龄的情况下,我使用像这样对赢得的赌注进行排序的密钥(感谢 Dimitre):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:key name="kOffspring" match="Horse" use="SireID"/>

 <xsl:template match="/*">
  <xsl:apply-templates select="Sires/Sire">
   <xsl:sort select="sum(key('kOffspring', ID)/*/Stakes)"
             data-type="number" order="descending"/>
  </xsl:apply-templates>
 </xsl:template>

 <xsl:template match="Sire">
    <!-- get the data I want -->
 </xsl:template>
</xsl:stylesheet>

现在,在“获取我想要的数据”中,我尝试只获取 3 岁的马(年龄=3) 例如,为了只获得 srA 的 3 岁获胜后代(答案 = 2),我需要这样的东西,我在想:

<xsl:value-of select="count(key('kOffspring', ID)[Age=3]/*/Wins)"/>

但这不起作用...或者我是否需要为每个年龄创建一个新密钥,我想使用一些条件语法(?),例如:

<xsl:key name="kOffspring" match="Horse[/Age=3]" use="SireID"/>

如你所见,我真的不知道我在做什么,也不知道这是否可能:-)

.

类似的另一种情况是需要计算有多少匹马是获胜者 - 答案=4(不是获胜次数,只是他们是否以配速或小跑获胜......第三种情况需要仅以配速或仅以速度小跑)。

我在父亲模板中尝试了这个:

<xsl:value-of select="count(key('kOffspring', ID)/*/Wins &gt; 0)"/>

但这只返回计数为一。

如果这里有任何专家可以帮助我前进,我将不胜感激。与其他编程语言相比,我发现 xslt 语法有点令人困惑且难以记住 - 我希望我能尽快掌握它,因为它非常强大。

问候, 布莱斯·斯坦伯格。

xslt xpath xslt-2.0
2个回答
3
投票

这个转变

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:key name="kOffspring" match="Horse" use="SireID"/>

 <xsl:template match="/*">
  <xsl:apply-templates select="Sires/Sire">
   <xsl:sort select="sum(key('kOffspring', ID)/*/Stakes)"
             data-type="number" order="descending"/>
  </xsl:apply-templates>
 </xsl:template>

 <xsl:template match="Sire">
     Sire <xsl:value-of select="concat(ID,' (', Name, ') Stakes: ')"/>
   <xsl:value-of select="sum(key('kOffspring', ID)/*/Stakes)"/>
     3 year old winning offspring: <xsl:value-of
     select="count(key('kOffspring', ID)[Age = 3 and */Wins > 0])"/>
     Offspring that ever were a winner: <xsl:value-of
      select="count(key('kOffspring', ID)[*/Wins > 0])"/>
 </xsl:template>
</xsl:stylesheet>

应用于提供的 XML 时(提供的片段,包含在单个顶部元素中以使其成为格式良好的 XML 文档):

<t>
    <Horses>
        <Horse>
            <ID>1</ID>
            <Name>hrsA</Name>
            <SireID>101</SireID>
            <Age>3</Age>
            <Pace>
                <Stakes>20</Stakes>
                <Wins>0</Wins>
            </Pace>
        </Horse>
        <Horse>
            <ID>2</ID>
            <Name>hrsB</Name>
            <SireID>101</SireID>
            <Age>6</Age>
            <Pace>
                <Stakes>1600</Stakes>
                <Wins>9</Wins>
            </Pace>
        </Horse>
        <Horse>
            <ID>3</ID>
            <Name>hrsC</Name>
            <SireID>101</SireID>
            <Age>3</Age>
            <Trot>
                <Stakes>200</Stakes>
                <Wins>2</Wins>
            </Trot>
        </Horse>
        <Horse>
            <ID>4</ID>
            <Name>hrsD</Name>
            <SireID>101</SireID>
            <Age>4</Age>
            <Pace>
                <Stakes>50</Stakes>
                <Wins>0</Wins>
            </Pace>
            <Trot>
                <Stakes>100</Stakes>
                <Wins>1</Wins>
            </Trot>
        </Horse>
        <Horse>
            <ID>5</ID>
            <Name>hrsE</Name>
            <SireID>101</SireID>
            <Age>3</Age>
            <Pace>
                <Stakes>100</Stakes>
                <Wins>1</Wins>
            </Pace>
            <Trot>
                <Stakes>300</Stakes>
                <Wins>1</Wins>
            </Trot>
        </Horse>
    </Horses>
    <Sires>
        <Sire>
            <ID>101</ID>
            <Name>srA</Name>
            <LiveFoalsALL>117</LiveFoalsALL>
        </Sire>
    </Sires>
</t>

产生想要的正确结果:

 Sire 101 (srA) Stakes: 2370
 3 year old winning offspring: 2
 Offspring that ever were a winner: 4

或者,一个可能更有效的解决方案是使用另一个复合键,它的两个部分是

SireID
Age

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:key name="kOffspring" match="Horse" use="SireID"/>
 <xsl:key name="kOffspringBySireIdAndAge" match="Horse"
  use="concat(SireID, '+', Age)"/>

 <xsl:template match="/*">
  <xsl:apply-templates select="Sires/Sire">
   <xsl:sort select="sum(key('kOffspring', ID)/*/Stakes)"
             data-type="number" order="descending"/>
  </xsl:apply-templates>
 </xsl:template>

 <xsl:template match="Sire">
     Sire <xsl:value-of select="concat(ID,' (', Name, ') Stakes: ')"/>
   <xsl:value-of select="sum(key('kOffspring', ID)/*/Stakes)"/>
     3 year old winning offspring: <xsl:value-of
     select="count(key('kOffspringBySireIdAndAge', concat(ID, '+3'))
                       [*/Wins > 0]
                  )"/>
     Offspring that ever were a winner: <xsl:value-of
      select="count(key('kOffspring', ID)[*/Wins > 0])"/>
 </xsl:template>
</xsl:stylesheet>

当此转换应用于同一个 XML 文档(上面)时,会产生相同的正确结果

 Sire 101 (srA) Stakes: 2370
 3 year old winning offspring: 2
 Offspring that ever were a winner: 4

0
投票

创建一个变量,然后在测试中使用它。

<xsl:variable name="x" select="//x"/>
<xsl:choose>
    <xsl:when test="$x='false'">
    <rel:email><xsl:value-of select="//email"/></rel:email>
    </xsl:when>
    <xsl:otherwise>
        <rel:customer>
            <rel:org-id><xsl:value-of select="//org-id"/></rel:org-id>
        </rel:customer>
    </xsl:otherwise>
</xsl:choose>
© www.soinside.com 2019 - 2024. All rights reserved.