来源
<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>
问题:
它不会对属性“value”降序进行排序 - 这是因为前面的语句吗?
可在此处找到来源:http://xmlsoap.dk/xml/crCountLog.xml
答案 0 :(得分: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>
此方法选择没有小于其自身的项目的第一个项目,并仅将模板应用于该项目,将其余项目作为参数传递。然后选择下一个顶级项目,模板以递归方式自行调用,直到所有项目都用完为止。