我对编写xslt相当陌生,并且在尝试执行以下操作时遇到了麻烦。
我有一个xml文件,其中包含马的繁殖信息,分为两个主要部分。 1. Horses节点具有单个马匹的性能详细信息以及其父代的ID。 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模板并获得正确顺序的指示?
谢谢,
布莱斯·斯特伯格
最佳答案
此转换:
<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
说明:
我们定义一个键,该键指定
Horse
作为其SireID
的函数。仅通过在对标准XSLT Sire
函数的调用中提供其ID
来选择给定key()
的所有后代,这很有用-如下所示:key('kOffspring', ID)
。同样,给定
Stakes
的所有后代的Sire
之和为:sum(key('kOffspring', ID)/*/Stakes)
。我们将模板应用于XML文档中的所有
Sire
元素,并按其后代Stakes
的总和的递减值对它们进行排序。对于每个
Sire
,我们输出其ID
,Name
及其后代的Stakes
之和。