3

我对 xslt 编码相当陌生,并且在尝试执行以下操作时遇到了困难。

我有一个 xml 文件,其中包含分为两个主要部分的马的繁殖信息。1. Horses 节点有每匹马的表现细节以及他们父亲的身份。2. Sires 节点是Sires 的列表,还包含特定的育种统计数据。

我需要根据他们的小马驹赢得的“赌注”总和(即在马节点中)对公牛列表进行排序。

所以一个缩减的 xml 文件看起来像这样:

<Horses>
    <Horse>
        <ID>1</ID>
        <Name>hrsA</Name>
        <SireID>101</SireID>
        <Pace>
            <Stakes>4800</Stakes>
        </Pace>
    </Horse>
    <Horse>
        <ID>2</ID>
        <Name>hrsB</Name>
        <SireID>102</SireID>
        <Pace>
            <Stakes>3600</Stakes>
        </Pace>
    </Horse>
    <Horse>
        <ID>3</ID>
        <Name>hrsC</Name>
        <SireID>102</SireID>
        <Pace>
            <Stakes>2800</Stakes>
        </Pace>
    </Horse>
    <Horse>
        <ID>4</ID>
        <Name>hrsD</Name>
        <SireID>101</SireID>
        <Pace>
            <Stakes>56</Stakes>
        </Pace>
    </Horse>
    <Horse>
        <ID>5</ID>
        <Name>hrsE</Name>
        <SireID>100</SireID>
        <Pace>
            <Stakes>20000</Stakes>
        </Pace>
    </Horse>
    <Horse>
        <ID>6</ID>
        <Name>hrsF</Name>
        <SireID>101</SireID>
        <Trot>
            <Stakes>20000</Stakes>
        </Trot>
    </Horse>
    <Horse>
        <ID>7</ID>
        <Name>hrsG</Name>
        <SireID>101</SireID>
        <Trot>
            <Stakes>559</Stakes>
        </Trot>
    </Horse>
    <Horse>
        <ID>8</ID>
        <Name>hrsH</Name>
        <SireID>102</SireID>
        <Pace>
            <Stakes>386</Stakes>
        </Pace>
        <Trot>
            <Stakes>10000</Stakes>
        </Trot>
    </Horse>
</Horses>
<Sires>
    <Sire>
        <ID>100</ID>
        <Name>srA</Name>
        <LiveFoalsALL>117</LiveFoalsALL>
    </Sire>
    <Sire>
        <ID>101</ID>
        <Name>srB</Name>
        <LiveFoalsALL>774</LiveFoalsALL>
    </Sire>
    <Sire>
        <ID>102</ID>
        <Name>srC</Name>
        <LiveFoalsALL>43</LiveFoalsALL>
    </Sire>
</Sires>

因此,将各种赌注相加,输出将具有以下顺序:

Sire 101 (srB) Stakes: $25415
Sire 100 (srA) Stakes: $20000
Sire 103 (srC) Stakes: $16768.

当我只是对其他网页的单个马桩进行汇总和排序时,我可以使用:

<xsl:apply-templates select="Horse">
    <xsl:sort select="sum(descendant::Stakes)" data-type="number"
        order="descending"/>
</xsl:apply-templates>

我只是不知道如何对引用马节点的公牛做同样的事情,以求和以获得正确的顺序......可能是这样的,我试图说 Sire/ID 等于 Horse/SireID:

<xsl:apply-templates select="Sire">
    <xsl:sort select="sum(//Horses/Horse[@SireID=ID]/descendant::Stakes)" 
        data-type="number" order="descending"/>
</xsl:apply-templates>

但这不起作用,调试器在到达排序行时会直接跳出当前模板,因此我的语法一定是无效的。我一直在尝试这个主题的变化,但没有成功。

谁能告诉我如何调用我的 Sire 模板并获得正确的顺序?

谢谢,

布莱斯斯坦伯格

4

2 回答 2

2

这种转变

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

应用于提供的 XML 文档时:

<t>
    <Horses>
        <Horse>
            <ID>1</ID>
            <Name>hrsA</Name>
            <SireID>101</SireID>
            <Pace>
                <Stakes>4800</Stakes>
            </Pace>
        </Horse>
        <Horse>
            <ID>2</ID>
            <Name>hrsB</Name>
            <SireID>102</SireID>
            <Pace>
                <Stakes>3600</Stakes>
            </Pace>
        </Horse>
        <Horse>
            <ID>3</ID>
            <Name>hrsC</Name>
            <SireID>102</SireID>
            <Pace>
                <Stakes>2800</Stakes>
            </Pace>
        </Horse>
        <Horse>
            <ID>4</ID>
            <Name>hrsD</Name>
            <SireID>101</SireID>
            <Pace>
                <Stakes>56</Stakes>
            </Pace>
        </Horse>
        <Horse>
            <ID>5</ID>
            <Name>hrsE</Name>
            <SireID>100</SireID>
            <Pace>
                <Stakes>20000</Stakes>
            </Pace>
        </Horse>
        <Horse>
            <ID>6</ID>
            <Name>hrsF</Name>
            <SireID>101</SireID>
            <Trot>
                <Stakes>20000</Stakes>
            </Trot>
        </Horse>
        <Horse>
            <ID>7</ID>
            <Name>hrsG</Name>
            <SireID>101</SireID>
            <Trot>
                <Stakes>559</Stakes>
            </Trot>
        </Horse>
        <Horse>
            <ID>8</ID>
            <Name>hrsH</Name>
            <SireID>102</SireID>
            <Pace>
                <Stakes>386</Stakes>
            </Pace>
            <Trot>
                <Stakes>10000</Stakes>
            </Trot>
        </Horse>
    </Horses>
    <Sires>
        <Sire>
            <ID>100</ID>
            <Name>srA</Name>
            <LiveFoalsALL>117</LiveFoalsALL>
        </Sire>
        <Sire>
            <ID>101</ID>
            <Name>srB</Name>
            <LiveFoalsALL>774</LiveFoalsALL>
        </Sire>
        <Sire>
            <ID>102</ID>
            <Name>srC</Name>
            <LiveFoalsALL>43</LiveFoalsALL>
        </Sire>
    </Sires>
</t>

产生想要的正确结果

 Sire 101 (srB) Stakes: 25415
 Sire 100 (srA) Stakes: 20000
 Sire 102 (srC) Stakes: 16786

说明

  1. 我们定义一个键,指定 aHorse作为它的函数SireID。这在选择给定的所有后代时很有用,只需在调用标准 XSLT函数Sire时提供它——就像这样: .IDkey()key('kOffspring', ID)

  2. Stakes类似地,给定的所有后代的总和Sire是:sum(key('kOffspring', ID)/*/Stakes)

  3. 我们将模板应用于 XML 文档中的所有元素,并按其后代Sire的总和的递减值对这些元素进行排序。Stakes

  4. 对于每个Sire我们输出它的ID,以及它的后代Name的总和。Stakes

于 2012-11-21T22:06:28.290 回答
1

您需要使用current()

<xsl:apply-templates select="Sire">
    <xsl:sort select="sum(//Horses/Horse[SireID = current()/ID]//Stakes)" 
        data-type="number" order="descending"/>

current()为您提供当前 XPath 表达式之外的上下文节点;在这种情况下,当前<Sire>元素由 选择xsl:apply-templates。在谓词内部,上下文节点是<Horse>针对谓词表达式进行测试的元素。

笔记:

  • 你有一个@你不想要的;@ID指的是一个 ID属性
  • 我替换descendant::///
  • 正如@Dimitre 所指出的,如果您使用键而不是//foo[barID = current()/ID].
于 2012-11-21T22:04:39.347 回答