XSLT:基于来自其他节点的值的总和进行排序 [英] XSLT: Sorting based on sum of values from other nodes
问题描述
我对编写 xslt 还是比较陌生,并且在尝试执行以下操作时遇到了困难.
我有一个 xml 文件,其中包含分为两个主要部分的马匹育种信息.1. Horses 节点有个别马匹的表现细节以及他们的父亲是谁的id.2. Sires节点是拥有育种特定统计数据的Sires列表.
我需要根据他们的小马驹(即在马节点中)赢得的赌注"总和来对公牛列表进行排序.
所以一个精简的 xml 文件看起来像这样:
<马><ID>1</ID><姓名>hrsA</姓名><SireID>101</SireID><节奏><本金>4800</本金></步速></马><马><ID>2</ID><姓名>hrsB</姓名><SireID>102</SireID><节奏><本金>3600</本金></步速></马><马><ID>3</ID><姓名>hrsC</姓名><SireID>102</SireID><节奏><本金>2800</本金></步速></马><马><ID>4</ID><姓名>hrsD</姓名><SireID>101</SireID><节奏><赌注>56</赌注></步速></马><马><ID>5</ID><姓名>hrsE</姓名><SireID>100</SireID><节奏><赌注>20000</赌注></步速></马><马><ID>6</ID><姓名>hrsF</姓名><SireID>101</SireID><小跑><赌注>20000</赌注></马><马><ID>7</ID><姓名>hrsG</姓名><SireID>101</SireID><小跑><赌注>559</赌注></马><马><ID>8</ID><姓名>hrsH</姓名><SireID>102</SireID><节奏><赌注>386</赌注></步速><小跑><本金>10000</本金></马></马匹><公会><陛下><ID>100</ID><姓名>srA</姓名><LiveFoalsALL>117</LiveFoalsALL></陛下><陛下><ID>101</ID><姓名>srB</姓名><LiveFoalsALL>774</LiveFoalsALL></陛下><陛下><ID>102</ID><名称>srC</名称><LiveFoalsALL>43</LiveFoalsALL></陛下></Sires>
因此将各种赌注相加,输出将具有以下顺序:
Sire 101 (srB) 赌注:$25415爵士 100 (srA) 赌注:20000 美元Sire 103 (srC) 赌注:$16768.
当我刚刚为其他网页汇总和订购单个马匹时,我可以使用:
<xsl:sort select="sum(descendant::Stakes)" data-type="number"order="降序"/></xsl:apply-templates>
我只是不知道如何对引用马节点的公牛做同样的事情来求和以获得正确的排序......可能是这样的,我试图说公牛/ID等于马/SireID:
<xsl:sort select="sum(//Horses/Horse[@SireID=ID]/descendant::Stakes)"数据类型=数字"顺序=降序"/></xsl:apply-templates>
但这不起作用,调试器在遇到排序行时直接跳出当前模板,因此我的语法一定无效.我一直在尝试改变这个主题,但没有成功.
谁能告诉我如何调用我的 Sire 模板并获得正确的排序?
谢谢,
布莱斯·斯坦伯格
这种转变:
<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)"数据类型=数字"顺序=降序"/></xsl:apply-templates></xsl:模板><xsl:template match="Sire">陛下 <xsl:value-of select="concat(ID,' (', Name, ') Stakes: ')"/><xsl:value-of select="sum(key('kOffspring', ID)/*/Stakes)"/></xsl:模板><xsl:template match="text()"/></xsl:stylesheet>
应用于提供的 XML 文档时:
<马><马><ID>1</ID><姓名>hrsA</姓名><SireID>101</SireID><节奏><本金>4800</本金></步速></马><马><ID>2</ID><姓名>hrsB</姓名><SireID>102</SireID><节奏><本金>3600</本金></步速></马><马><ID>3</ID><姓名>hrsC</姓名><SireID>102</SireID><节奏><本金>2800</本金></步速></马><马><ID>4</ID><姓名>hrsD</姓名><SireID>101</SireID><节奏><赌注>56</赌注></步速></马><马><ID>5</ID><姓名>hrsE</姓名><SireID>100</SireID><节奏><赌注>20000</赌注></步速></马><马><ID>6</ID><姓名>hrsF</姓名><SireID>101</SireID><小跑><赌注>20000</赌注></马><马><ID>7</ID><姓名>hrsG</姓名><SireID>101</SireID><小跑><赌注>559</赌注></马><马><ID>8</ID><姓名>hrsH</姓名><SireID>102</SireID><节奏><赌注>386</赌注></步速><小跑><本金>10000</本金></马></马匹><公会><陛下><ID>100</ID><姓名>srA</姓名><LiveFoalsALL>117</LiveFoalsALL></陛下><陛下><ID>101</ID><姓名>srB</姓名><LiveFoalsALL>774</LiveFoalsALL></陛下><陛下><ID>102</ID><名称>srC</名称><LiveFoalsALL>43</LiveFoalsALL></陛下></Sires></t>
产生想要的、正确的结果:
Sire 101 (srB) 赌注:25415Sir 100 (srA) 赌注:20000Sire 102 (srC) 赌注:16786
说明:
我们定义了一个键,该键将
Horse
指定为其SireID
的函数.这对于选择给定Sire
的所有后代非常有用,只需在调用标准 XSLTkey()
函数——像这样:key('kOffspring', ID)
.同样,给定
Sire
的所有后代的Stakes
总和是:sum(key('kOffspring', ID)/*/赌注)
.我们将模板应用于 XML 文档中的所有
Sire
元素,并按其后代Stakes
总和的递减值对这些元素进行排序.>对于每个
Sire
,我们输出它的ID
、Name
和它的Stakes
的总和后代.
I'm rather new to coding xslt and have got rather stuck trying to do the following.
I have an xml file that has breeding info for horses broken into two main sections. 1. Horses node has the performance details of individual horses as well as an id to who their sire was. 2. Sires node is list of the Sires also holding breeding specific statistics.
I need to sort the list of sires based on the sum of the 'stake' money won by their foals (i.e. in the horses node).
So a cut down xml file looks like this:
<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>
So summing the various stakes the output would have this ordering:
Sire 101 (srB) Stakes: $25415
Sire 100 (srA) Stakes: $20000
Sire 103 (srC) Stakes: $16768.
When I was just summing and ordering the individual horse stakes for other web pages I was able to use:
<xsl:apply-templates select="Horse">
<xsl:sort select="sum(descendant::Stakes)" data-type="number"
order="descending"/>
</xsl:apply-templates>
I just can't figure out how to do the same for the sires referencing the horse node for summing to get the right ordering... possibly something like this where I try to say the Sire/ID is equal to the 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>
But that doesn't work, the debugger jumps straight out of the current template when it hits the sort line so my syntax must be invalid. I've been trying variations on this theme without success.
Can anyone please give me a pointer of how to call my Sire template and get the correct ordering?
Thanks,
Bryce Stenberg
This transformation:
<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>
when applied on the provided XML document:
<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>
produces the wanted, correct result:
Sire 101 (srB) Stakes: 25415
Sire 100 (srA) Stakes: 20000
Sire 102 (srC) Stakes: 16786
Explanation:
We define a key that specifies a
Horse
as a function of itsSireID
. This is useful in selecting all offspring of a givenSire
just by providing itsID
in a call to the standard XSLTkey()
function -- like this:key('kOffspring', ID)
.Similarly, the sum of
Stakes
of all offspring of a givenSire
is:sum(key('kOffspring', ID)/*/Stakes)
.We apply templates to all
Sire
elements in the XML document and sort these by the decreasing values of the sums of theStakes
of their offsprings.For each
Sire
we output itsID
,Name
and the sum ofStakes
of its offspring.
这篇关于XSLT:基于来自其他节点的值的总和进行排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!