for-each-group和sort(但忽略一些值)

时间:2017-01-27 15:38:25

标签: xslt-2.0 xpath-2.0

考虑这个源XML:

<interesting value="yes"/>

现在我想将所有自行车和所有车辆组合在一起,但订单应该是价格(便宜到昂贵),但只考虑带<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0"> <xsl:output indent="yes"/> <xsl:template match="/"> <xsl:apply-templates/> </xsl:template> <xsl:template match="root"> <out> <xsl:for-each-group select="value" group-by="type/@name"> <xsl:sort select="@price" data-type="number"/> <elt> <xsl:attribute name="grouping-key" select="current-grouping-key()"/> <xsl:attribute name="min-price" select="@price"/> </elt> </xsl:for-each-group> </out> </xsl:template> </xsl:stylesheet> 的自行车和汽车。

我的XSLT

<interesting value="yes"/>

忽略<out> <elt grouping-key="car" min-price="1"/> <elt grouping-key="bike" min-price="50"/> </out> 的过滤。结果是

<out>
   <elt grouping-key="bike" min-price="123"/>
   <elt grouping-key="car" min-price="150"/>
</out>

但它应该是

bike[interesting/@value='yes']

因为car[interesting/@value='yes']interesting="yes"

便宜

每辆车可以有两种以上的类型,{{1}}可以有更多的条目。

我如何按价格排序,但只考虑那些“有趣”的?

2 个答案:

答案 0 :(得分:1)

只需通过添加谓词来过滤您在<xsl:for-each-group中选择的元素:

  <xsl:for-each-group select="value[interesting/@value='yes']" group-by="type/@name">

结果是:

<?xml version="1.0" encoding="UTF-8"?>
<out>
   <elt grouping-key="bike" min-price="123"/>
   <elt grouping-key="car" min-price="150"/>
</out>

答案 1 :(得分:1)

解决方案可能比它应该更复杂,但现在是:

<xsl:for-each-group select="value" group-by="type/@name">
   <xsl:sort select="not(empty(current-group()[interesting[@value = 'yes']]))" order="descending"/>
   <xsl:sort select="(min(current-group()[interesting[@value = 'yes']]/xs:integer(@price)), min(current-group()/xs:integer(@price)))[1]" data-type="number"/>

   <xsl:variable name="sorted-items" as="node()*">
      <xsl:perform-sort select="current-group()">
         <xsl:sort select="interesting[@value = 'yes']" order="descending"/>
         <xsl:sort select="@price" data-type="number"/>
      </xsl:perform-sort>
   </xsl:variable>

   <elt>
      <xsl:attribute name="grouping-key" select="current-grouping-key()"/>
      <xsl:attribute name="min-price" select="$sorted-items[1]/@price"/>
   </elt>
</xsl:for-each-group>