2013-02-11 77 views
1

来源XSLT排序问题 - 属性不会排序

<roll> 
    <dayquantum date="20130125"> 
    <item index="2" value="4" product="Margherita"/> 
    <item index="3" value="2" product="Capricciosa"/> 
    <item index="4" value="2" product="Quattro Stagioni"/> 
    <item index="5" value="7" product="Bresola"/> 
    <item index="6" value="1" product="Gorgonzola"/> 
    <item index="7" value="7" product="Piccante"/> 
    <item index="8" value="3" product="Rosmarino"/> 
    <item index="9" value="2" product="Caprese"/> 
    <item index="10" value="7" product="Parma"/> 
    <item index="11" value="1" product="Parmigiana"/> 
    <item index="12" value="2" product="Pollo"/> 
    <item index="13" value="2" product="Hawaii"/> 
    <item index="14" value="17" product="Pepperoni"/> 
    <item index="15" value="4" product="Calzone"/> 
    <item index="16" value="2" product="Bologna"/> 
    <item index="17" value="3" product="Tonno"/> 
    <item index="18" value="1" product="Marinara"/> 
    <item index="19" value="2" product="Napoletana"/> 
    <item index="20" value="1" product="Carne"/> 
    <item index="21" value="1" product="Mascarpone"/> 
    <item index="22" value="4" product="Carpaccio"/> 
    <item index="25" value="1" product="Tartufo"/> 
    <item index="26" value="8" product="Prosciutto"/> 
    <item index="27" value="3" product="Lasagna Originale"/> 
    <item index="28" value="1" product="Tortellini Gorgonzola"/> 
    <item index="29" value="1" product="Tortellini Tartufo"/> 
    <item index="31" value="4" product="Tagliatelle Dolce Vita"/> 
    <item index="33" value="1" product="Spaghetti Carbonara"/> 
    <item index="37" value="2" product="Antipasta Toto e Pepino"/> 
    <item index="38" value="1" product="Vitello Tonnato"/> 
    <item index="41" value="4" product="Bruschetta classica"/> 
    <item index="44" value="1" product="Tiramisu"/> 
    <item index="47" value="4" product="Panino al Pollo"/> 
    <item index="48" value="5" product="Panino al Prosciutto"/> 
    <item index="49" value="8" product="Panino al vitello tonnato"/> 
    </dayquantum> 
</roll> 

XSLT

<svg viewBox="0 0 2400 1400" style="background: #000 ; font-family: 'Racing Sans One'" id="zcanvas" version="1.1" xsl:version="1.0" 
    xmlns:xlink="http://www.w3.org/1999/xlink" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns="http://www.w3.org/2000/svg"> 
    <defs><link xmlns="http://www.w3.org/1999/xhtml" href="http://fonts.googleapis.com/css?family=Racing+Sans+One|Six+Caps" type="text/css" rel="stylesheet" /></defs> 

    <xsl:for-each select="roll/dayquantum"> 
     <xsl:sort select="@date" order="descending" data-type="number"/> 

     <xsl:variable name="y" select="(position() * 180) - 100" />  

     <text fill="#fff" font-size="48">  
     <xsl:attribute name="x"><xsl:value-of select="80" /></xsl:attribute>    
     <xsl:attribute name="y"><xsl:value-of select="$y - 40" /></xsl:attribute>   
     <xsl:attribute name="transform">rotate(90, 80, <xsl:value-of select="$y - 40 " />)</xsl:attribute>      
     <xsl:value-of select="substring(@date,7,2)" /><xsl:value-of select="substring(' JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC', number(substring(@date,5,2)) * 3, 3)" />   
     </text> 
     <text fill="#ff6000" font-size="48">  
     <xsl:attribute name="x"><xsl:value-of select="120" /></xsl:attribute>    
     <xsl:attribute name="y"><xsl:value-of select="$y - 10" /></xsl:attribute>   
     <xsl:value-of select="sum(item/@value)" /> 
     </text> 

     <xsl:for-each select="item">  
     <xsl:sort select="@value" order="descending" data-type="number"/> 
     <rect fill="green" >  
      <xsl:attribute name="x"><xsl:value-of select="200 + (sum(preceding-sibling::item/@value) * 16)" /></xsl:attribute>    
      <xsl:attribute name="y"><xsl:value-of select="$y - 48" /></xsl:attribute>   
      <xsl:attribute name="width"><xsl:value-of select="@value * 16" /></xsl:attribute>    
      <xsl:attribute name="rx">10</xsl:attribute>   
      <xsl:attribute name="height">48</xsl:attribute>   
     </rect> 
     <g font-family="sans-serif"> 
     <text fill="#fff" font-size="20" text-anchor="middle">  
      <xsl:attribute name="x"><xsl:value-of select="200 + (sum(preceding-sibling::item/@value) * 16) + ((@value * 16) div 2)" /></xsl:attribute>    
      <xsl:attribute name="y"><xsl:value-of select="$y - 20" /></xsl:attribute>   
      <xsl:value-of select="@value" /> 
     </text>  
     <text fill="#888" font-size="18" text-anchor="start">  
      <xsl:attribute name="x"><xsl:value-of select="200 + (sum(preceding-sibling::item/@value) * 16) + ((@value * 16) div 2)" /></xsl:attribute>    
      <xsl:attribute name="y"><xsl:value-of select="$y" /></xsl:attribute>   
      <xsl:attribute name="transform">rotate(90, <xsl:value-of select="200 + (sum(preceding-sibling::item/@value) * 16) + ((@value * 16) div 2)" />, <xsl:value-of select="$y" />)</xsl:attribute>    
      <xsl:value-of select="@product" /> 
     </text> 
     </g> 
     </xsl:for-each>  
    </xsl:for-each> 
    </svg> 

问题:

它不会排序属性 “价值” 下降 - 是因为前述声明?

源可以在这里找到:http://xmlsoap.dk/xml/crCountLog.xml

+0

我期待的项目是以递减的方式呈现 即最初的数值最高的项目 这是SVG,你应该在非ie浏览器中看到结果... 你是对的 - 我有同步XSLT和上述... – Mike 2013-02-11 09:15:13

回答

2

的原因,它不工作,你期望的方式是preceding-sibling::着眼于item S'前面的兄弟姐妹在文档顺序,而不是当前的排序顺序。所以他们正在排序,但正在计算x的值,好像你根本没有对它们进行排序。

以下递归方法应达到什么样的你正在尝试做的:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" 
       xmlns="http://www.w3.org/2000/svg"> 
    <xsl:output method="xml" omit-xml-declaration="yes" /> 

    <xsl:template match="/"> 
    <svg viewBox="0 0 2400 1400" 
     style="background: #000 ; font-family: 'Racing Sans One'" id="zcanvas" 
     version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink"> 
     <defs> 
     <link xmlns="http://www.w3.org/1999/xhtml" 
       href="http://fonts.googleapis.com/css?family=Racing+Sans+One|Six+Caps" 
       type="text/css" rel="stylesheet" /> 
     </defs> 

     <xsl:apply-templates select="roll/dayquantum"> 
     <xsl:sort select="@date" order="descending" data-type="number"/> 
     </xsl:apply-templates> 
    </svg> 
    </xsl:template> 

    <xsl:template match="dayquantum"> 
    <xsl:variable name="y" select="(position() * 180) - 100" /> 

    <text fill="#fff" font-size="48" x="80" y="{$y - 40}" 
      transform="rotate(90, 80, {$y - 40})"> 
     <xsl:value-of select="substring(@date,7,2)" /> 
     <xsl:value-of select="substring(' JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC', 
          number(substring(@date,5,2)) * 3, 3)" /> 
    </text> 
    <text fill="#ff6000" font-size="48" x="120" y="{$y - 10}"> 
     <xsl:value-of select="sum(item/@value)" /> 
    </text> 

    <xsl:variable name="topItem" select="item[not(../item/@value > @value)][1]" /> 
    <xsl:apply-templates select="$topItem"> 
     <xsl:with-param name="y" select="$y" /> 
     <xsl:with-param name="remainingItems" 
         select="item[generate-id() != generate-id($topItem)]" /> 
    </xsl:apply-templates> 
    </xsl:template> 

    <xsl:template match="item"> 
    <xsl:param name="y" /> 
    <xsl:param name="previousItems" select="/.." /> 
    <xsl:param name="remainingItems" /> 

    <xsl:variable name="leadingSpace" 
        select="200 + sum($previousItems/@value) * 16" /> 
    <xsl:variable name="width" select="@value * 16" /> 
    <xsl:variable name="hCenter" select="$leadingSpace + $width div 2" /> 

    <rect fill="green" x="{$leadingSpace}" y="{$y - 48}" width="{$width}" 
      rx="10" height="48" /> 

    <g font-family="sans-serif"> 
     <text fill="#fff" font-size="20" text-anchor="middle" x="{$hCenter}" 
      y="{$y - 20}"> 
     <xsl:value-of select="@value" /> 
     </text> 

     <text fill="#888" font-size="18" text-anchor="start" x="{$hCenter}" 
      y="{$y}" transform="rotate(90, {$hCenter}, {$y})"> 
     <xsl:value-of select="@product" /> 
     </text> 
    </g> 

    <xsl:variable name="topItem" 
       select="$remainingItems[not($remainingItems/@value > @value)][1]" /> 
    <xsl:apply-templates select="$topItem"> 
     <xsl:with-param name="y" select="$y" /> 
     <xsl:with-param name="previousItems" select="$previousItems | ." /> 
     <xsl:with-param name="remainingItems" 
         select="$remainingItems[generate-id() != 
               generate-id($topItem)]" /> 
    </xsl:apply-templates> 
    </xsl:template> 


</xsl:stylesheet> 

这种方法选择与没有项目低于本身的第一个项目,并应用模板。不仅如此,通过剩余的项目作为参数。然后选择下一个顶层项目,模板递归调用自身,直到所有项目都用完。

+0

THX - 我很懒 - 所以你是对的 - 递归是解决方案... – Mike 2013-02-11 16:05:32

+1

不客气。而且我认为你需要更加懒惰,并使用更多属性值模板,而不是所有那些难看的'。 :)这是你在那里工作的一个非常漂亮的页面。我应该从这些日子开始学习SVG。 – JLRishe 2013-02-11 16:31:04

+0

我注意到你的简约方法 - 是的,我喜欢做SVG 灵感:http://xmlsoap.dk/cashregister/cr.xml 个人分析银行交易 - 你可以点击底部的点 http:// www .mrasch.dk/analyseTransactions2006_2010.xml 认为麦克风 – Mike 2013-02-11 17:02:53