XSLT:排序基于来自其他节点的值的总和(XSLT: Sorting based on sum of

2019-07-04 01:18发布

我是相当新的编码XSLT,并已得到了相当卡住努力做到以下几点。

我有一个具有繁殖马匹分为两个主要部分信息的XML文件。 1.马节点都有各自的马匹的表现细节,以及一个ID,谁是自己的父亲是。 2.赛瑞斯节点的赛瑞斯还抱着养殖具体的统计数据列表。

我需要梳理公牛的基础上,通过他们的马驹获得了“股权的钱(在马节点IE)的总和名单。

所以减少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>

我只是无法弄清楚如何为公牛引用马节点相加来得到正确的排序......可能是这样的,我尽量说陛下/ ID等于做同样的马/ SireID:

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

但是,这并不工作,调试器跳直出,当它击中的那种线,所以我的语法必须是无效的当前模板的。 我一直在试图对这一主题没有成功的变化。

任何人都可以请给我如何调用我的陛下模板,得到正确排序的指针?

谢谢,

布莱斯Stenberg发明

Answer 1:

这一转变

<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. 我们定义它指定了一个关键的Horse作为其的功能SireID 。 这是在选择一个给定的所有后代有用Sire刚刚通过提供其ID在该标准XSLT通话key()这样的-功能key('kOffspring', ID)

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

  3. 我们应用模板到所有Sire的XML文档中的元素和由之和的减少值进行排序,这些Stakes他们的后代。

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



Answer 2:

您需要使用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]


文章来源: XSLT: Sorting based on sum of values from other nodes