0

这个问题来自查询XSLT:Sorting based on sum of values from other nodes

我有这块 xslt(感谢 Demitre),我已经对其进行了修改以接收参数“Gait”,该参数可以具有值“P”(步伐)、“T”(小跑)或“A”(全部):

<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:param name="Gait"/>

 <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)"/>
 </xsl:template>
 <xsl:template match="text()"/>
</xsl:stylesheet>

在上面的代码中就是这块

sum(key('kOffspring', ID)/*/Stakes

有没有办法用 xml 树中的节点名称替换星号部分,具体取决于为步态传入的值?

超级简化的xml是:

<t>
    <Horses>
        <Horse>
            <ID>5</ID>
            <Name>hrsE</Name>
            <SireID>101</SireID>
            <Pace>
                <Stakes>100</Stakes>
            </Pace>
            <Trot>
                <Stakes>300</Stakes>
            </Trot>
        </Horse>
    </Horses>
    <Sires>
        <Sire>
            <ID>101</ID>
            <Name>srA</Name>
            <LiveFoalsALL>117</LiveFoalsALL>
        </Sire>
    </Sires>
</t>

当 $Gait 是 'A' 我想要 sum(key('kOffspring', ID)/*/Stakes (查看 Horse 的所有子节点)

当 $Gait 是 'P' 我想要 sum(key('kOffspring', ID)/Pace/Stakes(只在 Pace 节点中查找 Stakes)

当 $Gait 是 'T' 我想要 sum(key('kOffspring', ID)/Trot/Stakes(只在 Trot 节点中查找 Stakes)

所以这是一个超级简化的例子。我试图停止复制数百行代码来满足 $Gait 的不同值。我尝试使用变量,但看不到在使用路径中的键时如何更改节点路径的值。我看到我可以在 'match="/*"' 模板中使用选择语句,但这仅用于排序,当我进入 'Sire' 模板时我仍然被卡住 - 不想放'围绕我拥有的众多“选择价值”语句进行选择。

感谢您的任何建议。问候,布莱斯斯坦伯格。

4

2 回答 2

2

只需使用

sum(key('kOffspring', ID)/*[name()=$Gait]/Stakes
于 2012-11-26T07:33:46.550 回答
1
<xsl:value-of select="sum(key('kOffspring', ID)/*/Stakes)" />

有没有办法用 xml 树中的节点名称替换星号部分,具体取决于为步态传入的值?

是的...一种方法是在 XPath 表达式中添加一个“switch 语句”:

sum(key('kOffspring', ID)/*[
    $Gait = 'A' or
    (local-name() = (if ($Gait = 'P') then 'Pace' else
                        if ($Gait = 'T') then 'Trot'))
  ]/Stakes)

或者,您可以编写三个不同版本的<xsl:value-of>,为 $Gait 的每个可能值一个,并使用<xsl:choose>来选择使用哪一个:

<xsl:choose>
   <xsl:when test="$Gait = 'A'">
      <xsl:value-of select="sum(key('kOffspring', ID)/*/Stakes)" />
   </xsl:when>
   <xsl:when test="$Gait = 'P'">
      <xsl:value-of select="sum(key('kOffspring', ID)/Pace/Stakes)" />
   </xsl:when>
   etc.

<xsl:choose>对我来说似乎更具可读性,并且可能更有效,具体取决于处理器;但这在很大程度上是一个偏好问题。

于 2012-11-26T03:00:22.760 回答