2013-02-11 68 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