XSLT 按两个子属性对父对象进行排序

Posted

技术标签:

【中文标题】XSLT 按两个子属性对父对象进行排序【英文标题】:XSLT Sorting A Parent By Two Child Attributes 【发布时间】:2018-03-06 19:25:18 【问题描述】:

我正在尝试通过两个单独的子元素中的两个属性对父节点进行排序。具体来说,我想先按“attack/@pct”排序,然后按“misc/@pts”排序。下面是我的源代码:

<player uni="11" code="11" name="RACHEL, Devon" checkname="RACHEL,DEVON" class="JR" gp="4" ms="1">
  <attack k="14" e="1" ta="41" pct=".317"></attack>
  <set a="0" e="0" ta="2"></set>
  <serve sa="0" se="0" ta="6"></serve>
  <defense dig="3" re="2" ta="13"></defense>
  <block bs="0" ba="2" be="0" tb="2"></block>
  <misc bhe="0" pts="15.0"></misc>
</player>
<player uni="13" code="13" name="BECKMAN, Allison" checkname="BECKMAN,ALLISON" class="JR" gp="4" ms="1">
  <attack k="3" e="1" ta="4" pct=".500"></attack>
  <set a="51" e="0" ta="128"></set>
  <serve sa="0" se="0" ta="16"></serve>
  <defense dig="17" re="0" ta="0"></defense>
  <block bs="0" ba="2" be="1" tb="2"></block>
  <misc bhe="0" pts="4.0"></misc>
</player>
<player uni="2" code="2" name="MADISON, Kennedy" checkname="MADISON,KENNEDY" class="JR" gp="4">
  <attack k="14" e="7" ta="32" pct=".219"></attack>
  <set a="0" e="0" ta="3"></set>
  <serve sa="0" se="0" ta="0"></serve>
  <defense dig="3" re="0" ta="2"></defense>
  <block bs="0" ba="5" be="0" tb="5"></block>
  <misc bhe="1" pts="16.5"></misc>
</player>
<player uni="20" code="20" name="MUMMEY, Krissy" checkname="MUMMEY,KRISSY" class="SR" gp="4" ms="1">
  <attack k="12" e="4" ta="31" pct=".258"></attack>
  <set a="0" e="0" ta="1"></set>
  <serve sa="0" se="1" ta="8"></serve>
  <defense dig="5" re="0" ta="1"></defense>
  <block bs="0" ba="4" be="1" tb="4"></block>
  <misc bhe="0" pts="14.0"></misc>
</player>

基本上,我希望它吐出第一个玩家,即使她的 misc/@pts 和 attack/@pct 在任何一个单独的排序中都不会排名第一。这是我尝试过的代码,但它似乎遗漏了一些东西 - 它会按第一个排序,但完全忽略第二个。

<xsl:for-each select="player">
<xsl:sort select="attack/@pct" data-type="number" order="descending"/>
<xsl:sort select="misc/@pts" data-type="number" order="descending"/>
...
</xsl:for-each>

【问题讨论】:

在您的示例数据中,每个 都有一个不同的 attack/@pct 值。因此,第二个排序键与该数据无关。 如果要将数据按呈现的顺序排序,那么确定顺序的实际标准是什么?我猜attack/@pctmisc/@pts 的某种组合;在这种情况下,您希望将 组合 作为排序键。 我想按attack/@pct 排序,然后在该排序中按misc/@pts。基本上我遇到的是,得分最多的玩家并不总是最有效率的——这意味着得分少两到三分的玩家的攻击/@pct 可能会更高。也许它在为 misc/@pts 定义最小值(大于)时按攻击/@pct 排序? 例子:如果勒布朗詹姆斯 25 投 38 分,而斯蒂芬库里 15 投 30 分,谁会被认为更有效率? 你真的是说你想按他们的平均得分排序吗?所以斯蒂芬-库里,场均2分,排在勒布朗-詹姆斯之前,场均1.52分? 【参考方案1】:

根据您的 cmets,您 “希望将“attack/@pct”值至少为 0.300 的玩家按“misc/@pts”排序。 在这种情况下,表达式你要的是这个……

<xsl:sort select="misc[../attack/@pct &gt;= .300]/@pts" data-type="number" order="descending"/>

请注意,“attack/@pct”小于 0.300 的玩家仍会出现在输出中,没有特别的顺序,但在超过 0.300 的玩家之后。

【讨论】:

那行得通。谢谢!我感觉自己走在了正确的轨道上(在某种程度上),但我自己却无法完全弄清楚。

以上是关于XSLT 按两个子属性对父对象进行排序的主要内容,如果未能解决你的问题,请参考以下文章

XSLT 根据最大​​子节点对父节点进行排序

vue onclick 对父组件中的子组件进行排序

XSLT 对子子元素进行排序

Xslt:在利用数据之前重写树以对不同父母中的子属性进行排序

需要 XSLT 转换以删除重复元素 - 按属性排序

如何获取具有相同名称的元素并根据 XSLT 中的子节点值对它们进行排序