关于基于子元素计数的排序

时间:2015-06-22 12:49:57

标签: xml xslt

我有一个xml文档,其属性属于代理商:

<agency name="Century 42" num="Century42" mail="century42@gmail.com"/>
<property agency="Century42" ....>
...

我想打印所有代理商的信息。代理商应根据他们拥有的房产数量进行分类。

我尝试了这个,但它不起作用:

<xsl:apply-templates select="immo/agency">
<xsl:sort select="count(//property[@agency=@num])"/>
</xsl:apply-templates>

计数无效。

2 个答案:

答案 0 :(得分:0)

您可以使用键来计算排序指令中的属性。包含以下内容的样式表:

<xsl:key name="p" match="property" use="@agency"/>

<xsl:template match="/immo">
   <result>
      <xsl:for-each select="agency">
         <xsl:sort select="count(key('p', @name))"/>
         <res id="{ @name }" count="{ count(key('p', @name)) }"/>
     </xsl:for-each>
   </result>
</xsl:template>

应用于以下输入时:

<immo>
   <agency name="a"/>
   <agency name="b"/>
   <agency name="c"/>
   <property agency="a"/>
   <property agency="a"/>
   <property agency="a"/>
   <property agency="b"/>
   <property agency="b"/>
   <property agency="b"/>
   <property agency="b"/>
   <property agency="c"/>
</immo>

产生以下输出:

<result>
   <res id="c" count="1"/>
   <res id="a" count="3"/>
   <res id="b" count="4"/>
</result>

如果您想要相反的订单,请在order="descending"上使用xsl:sort

编辑:如果property/@agency可以有多个代理商号,由空格分隔,则以下解决方案可以正常工作(不使用密钥,并为每个代理商再次选择文档中的所有属性) ):

<xsl:template match="/immo">
   <result>
      <xsl:for-each select="agency">
         <xsl:sort select="count(//property[tokenize(@agency, '\s+') = current()/@name])"/>
         <res id="{ @name }"/>
     </xsl:for-each>
   </result>
</xsl:template>

答案 1 :(得分:0)

仅供参考,我收到了一个简单的回答我的问题

<xsl:apply-templates select="immo/agency">
<xsl:sort select="count(//property[contains(@agency, current()/@num)])" order="descending"/>
</xsl:apply-templates>