2015-02-24 70 views
1

我試圖更好地理解Muenchian分組。我僅限於XSL 1.0。我能夠按屬性進行分組,但我似乎無法通過元素值進行分組工作。XSLT Muenchian排序

我的XML看起來是這樣的:

<?xml version="1.0"?> 
<orders> 
    <order date="2015-01-01"> 
     <product amount="8">Apple</product> 
     <product amount="1">Pear</product> 
    </order> 
    <order date="2015-01-01"> 
     <product amount="1">Plum</product> 
     <product amount="5">Pear</product> 
    </order> 
    <order id="01" date="2015-01-03"> 
     <product amount="10">Pear</product> 
     <product amount="4">Plum</product> 
    </order> 
</orders> 

我想要實現的是建立一個SVG圖,它顯示了許多各水果是如何排序。因此,人們可以很容易地看到每個示例中哪些是最暢銷的水果。這應該是這樣的(注量,數字並不象上面的XML):

diagram: group by product

,我想出了到目前爲止的代碼如下:

<xsl:stylesheet version="1.0" 
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
      xmlns:svg="http://www.w3.org/2000/svg" > 


<xsl:variable name="baseline" select="480"/> 

<xsl:key name="group-by-product" match="product" use="." /> 

<xsl:template match="/orders"> 
    <svg:svg > 
     <svg:g> 
      <xsl:apply-templates select="order/product[generate-id(.)=generate-id(key('group-by-product',.)[1])]" /> 

      <!-- draw x- axis and y - axis --> 
      <svg:path style="stroke-width:2; stroke:black" > 
       <xsl:attribute name="d"> 
        <xsl:text>M 40 100 L 40 </xsl:text> 
        <xsl:value-of select="480"/> 
        <xsl:text> L </xsl:text> 
        <xsl:value-of select="2* count(order) * 40 + 80" /> 
        <xsl:text> </xsl:text> 
        <xsl:value-of select="$baseline"/> 
        <xsl:text> L 40 </xsl:text>     
        <xsl:value-of select="$baseline"/> 
        <xsl:text> Z</xsl:text> 
       </xsl:attribute> 
      </svg:path> 
     </svg:g> 
    </svg:svg> 
</xsl:template> 

<xsl:template match="order"> 
    <xsl:variable name="y" select="sum(key('order-by-product',product)/@amount)"/> 
    <svg:rect x="{40 * position()+20}" y="{$baseline - $y}" width="30" height="{$y}" style="fill:blue"/> 
    <svg:text style="writing-mode:tb" x="{41 * position()+20}" y="{$baseline - $y - 10}"> 
     <xsl:value-of select="$y" /> 
    </svg:text> 
    <svg:text style="writing-mode:tb" x="{41 * position()+15}" y="{$baseline + 20}"> 
     <xsl:value-of select="product" /> 
    </svg:text>       
</xsl:template> 
</xsl:stylesheet> 

我覺得就像我在我的代碼中有一些不一致的地方,並且把自己與我已經看過的所有不同的例子混淆起來。 如果可能,我想避免使用「for-each」並使用「apply-template」。

謝謝你的幫助!

回答

2

你已經得到了Muenchian分組的邏輯正確,但模板錯了 - 你apply-templates選擇product元素:

<xsl:apply-templates select="order/product[generate-id(.)=generate-id(key('group-by-product',.)[1])]" /> 

但你的第二個模板相匹配order元素,因此它永遠不會火。你需要改變它像

<xsl:template match="product"> 
    <xsl:variable name="y" select="sum(key('order-by-product',.)/@amount)"/> 
    <svg:rect x="{40 * position()+20}" y="{$baseline - $y}" width="30" height="{$y}" style="fill:blue"/> 
    <svg:text style="writing-mode:tb" x="{41 * position()+20}" y="{$baseline - $y - 10}"> 
     <xsl:value-of select="$y" /> 
    </svg:text> 
    <svg:text style="writing-mode:tb" x="{41 * position()+15}" y="{$baseline + 20}"> 
     <xsl:value-of select="." /> 
    </svg:text>       
</xsl:template> 
+0

嗨伊恩。非常感謝您指出這一點。現在完美的工作!我還在匹配=「產品」模板的第2行上有一箇舊的密鑰名稱。它應該看起來像這樣: '' – Ohaio 2015-02-24 17:41:28