关于xslt count()

时间:2012-05-02 03:30:34

标签: xml xslt

我想要一个文本输出,显示歌曲标题和排名第一的周数。但是,我不知道如何在xslt中使用count。任何人都可以帮我找出我的代码有什么问题吗?我现在的代码没有任何输出。

<?xml version='1.0'?>
<xsl:stylesheet 
    version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:output encoding="UTF-8" omit-xml-declaration="yes" />  
<xsl:template match="/">
    <xsl:for-each select="popular-recordings-dataset/recording">
    <xsl:sort select="count(//rank[. = '1'])" order="descending"/>
    <xsl:value-of select="concat(title, ' / ', count(//rank[. = '1']),'&#xA;')" />
    </xsl:for-each>    
</xsl:template>   
</xsl:stylesheet>

1 个答案:

答案 0 :(得分:1)

此转化

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>

 <xsl:template match="/*">
  <xsl:apply-templates select="recording">
    <xsl:sort select="count(week/rank[. = 1])"
         data-type="number" order="descending"/>
  </xsl:apply-templates>
 </xsl:template>

 <xsl:template match="recording">
  <xsl:value-of select=
  "concat(title, ' / ', count(week/rank[. = 1]), '&#xA;')"/>
 </xsl:template>
</xsl:stylesheet>

应用于以下XML文档(问题中未提供!!!):

<popular-recordings-dataset>
  <recording>
   <title>Song1</title>
   <week no="23">
    <rank>1</rank>
   </week>
   <week no="24">
    <rank>2</rank>
   </week>
  </recording>
  <recording>
   <title>Song2</title>
   <week no="22">
    <rank>1</rank>
   </week>
   <week no="24">
    <rank>1</rank>
   </week>
   <week no="25">
    <rank>1</rank>
   </week>
  </recording>
  <recording>
   <title>Song3</title>
   <week no="21">
    <rank>1</rank>
   </week>
   <week no="26">
    <rank>1</rank>
   </week>
  </recording>
</popular-recordings-dataset>

生成想要的正确结果

Song2 / 3
Song3 / 2
Song1 / 1

解释:代码的问题在于使用此表达式:

count(//rank[. = '1']) 

count()的参数是绝对 XPath表达式(以/开头),因此它选择文档中所有rank个元素,其值等于1。这意味着此表达式不依赖于当前rank元素并随之变化,并且对于所有rank元素保持不变。对常量进行排序不会改变节点集的初始顺序 - 正如您所见过的那样。

<强>解决方案

更改

count(//rank[. = '1']) 

count(.//rank[. = '1']) 

但更好的是,如果事先知道XML文档的结构,那么尽量避免使用//伪运算符,这可能非常低效。