2011-03-16 31 views
0

我的xslt-fu仍然非常弱。早些年。XSLT:一次性計算篩選子集和全套數據的結果

我的XML數據是公司,他們的服務提供商和他們的價值的列表。

我已經設法按服務提供商分組,所以我可以看到哪些服務提供商在客戶數量和總體市場價值中擁有最多的市場份額。

這適用於整個市場,但我也想爲「前100名(按價值)公司」獲取價值。我不知道如何添加這個。

當前XSLT(見這裏我想補充的額外數據註釋):

<xsl:stylesheet xmlns:x="http://www.w3.org/2001/XMLSchema" xmlns:d="http://schemas.microsoft.com/sharepoint/dsp" version="1.0" exclude-result-prefixes="xsl msxsl ddwrt" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" xmlns:asp="http://schemas.microsoft.com/ASPNET/20" xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:SharePoint="Microsoft.SharePoint.WebControls" xmlns:ddwrt2="urn:frontpage:internal"> 
    <xsl:output method="html" indent="no"/> 

    <xsl:key name="providerkey" match="/dsQueryResponse/Rows/Row" use="@svcprovider" /> 

    <xsl:template match="/"> 
     <table> 
      <tr> 
       <th>Service Provider</th> 
       <th>Total Market value</th> 
       <th>No. Cos</th> 
       <th>Market value from top 100 cos</th> 
       <th>No. cos from top 100</th> 
      </tr> 

      <xsl:for-each select="/dsQueryResponse/Rows/Row[generate-id(.)=generate-id(key('providerkey',@svcprovider)[1])]"> 
       <xsl:sort select="count(key('providerkey',@svcprovider))" order="descending" data-type="number" /> 
       <xsl:variable name="totalvalue" select="sum(/dsQueryResponse/Rows/Row[@svcprovider=current()/@svcprovider]/@covalue)" /> 
       <tr> 
        <td> 
         <xsl:value-of select="current()/@svcprovider"/> 
        </td> 
        <td> 
         <xsl:value-of select="$totalvalue" /> 
        </td> 
        <td> 
         <xsl:value-of select="count(key('providerkey',@svcprovider))"/> 
        </td> 
        <td> 
         <!-- How do I get total value, but only from the top 100 companies ?? --> 
        </td> 
        <td> 
         <!-- How do I get total no. of companies, but only from the top 100 ?? --> 
        </td>      

       </tr> 
      </xsl:for-each> 
     </table> 
    </xsl:template> 

</xsl:stylesheet> 

示例XML數據:

<Rows> 
    <Row coname="client name 1" svcprovider="svc provider name 1" covalue="998" /> 
    <Row coname="client name 2" svcprovider="svc provider name 2" covalue="1081" /> 
    <!-- ...etc... --> 

</Rows> 

顯然,有超過100行。基本上我使用這個來計算整個市場的市場份額,並且還想計算高端產品。

我希望我需要添加一個額外的排序/過濾循環,但我不知道如何去嵌套它。

在此先感謝

約翰

回答

1

嘗試這樣的:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:msxsl="urn:schemas-microsoft-com:xslt" 
exclude-result-prefixes="msxsl"> 
    <xsl:output method="html" indent="yes"/> 
    <xsl:param name="pTopNumber" select="3"/> 

    <xsl:key name="providerkey" 
     match="/dsQueryResponse/Rows/Row" use="@svcprovider" /> 

    <xsl:variable name="vrtfTopCompanies"> 
    <xsl:for-each select="/*/*/Row"> 
     <xsl:sort select="covalue" 
      data-type="number" order="descending"/> 
     <xsl:if test="not(position() > $pTopNumber)"> 
     <xsl:copy-of select="."/> 
     </xsl:if> 
    </xsl:for-each> 
    </xsl:variable> 

    <xsl:variable name="vTopRows" 
     select="msxsl:node-set($vrtfTopCompanies)/*"/> 

    <xsl:template match="/"> 
     <table> 
      <tr> 
       <th>Service Provider</th> 
       <th>Total Market value</th> 
       <th>No. Cos</th> 
       <th>Market value from top 100 cos</th> 
       <th>No. cos from top 100</th> 
      </tr> 
      <xsl:for-each select= 
       "/dsQueryResponse/Rows/Row 
         [generate-id() 
         = 
         generate-id(key('providerkey',@svcprovider)[1]) 
         ]"> 
       <xsl:sort select="count(key('providerkey',@svcprovider))" 
          order="descending" data-type="number" /> 
       <xsl:variable name="totalvalue" select= 
        "sum(/dsQueryResponse/Rows 
           /Row[@svcprovider=current()/@svcprovider]/@covalue)" /> 
       <tr> 
        <td> 
         <xsl:value-of select="current()/@svcprovider"/> 
        </td> 
        <td> 
         <xsl:value-of select="$totalvalue" /> 
        </td> 
        <td> 
         <xsl:value-of select="count(key('providerkey',@svcprovider))"/> 
        </td> 
        <td> 
         <!-- How do I get total value, but only from the top 100 companies ?? --> 
         <xsl:value-of select="sum($vTopRows[@svcprovider=current()/@svcprovider]/@covalue)"/> 
        </td> 
        <td> 
         <!-- How do I get total no. of companies, but only from the top 100 ?? --> 
         <xsl:value-of select="count(key('providerkey',@svcprovider)[@coname = $vTopRows/@coname])"/> 
        </td> 
       </tr> 
      </xsl:for-each> 
     </table> 
    </xsl:template> 
</xsl:stylesheet> 

當下面的XML文檔應用:

<dsQueryResponse> 
    <Rows> 
     <Row coname="client name 1" svcprovider="svc provider name 1" covalue="998" /> 
     <Row coname="client name 2" svcprovider="svc provider name 2" covalue="1081" /> 
     <Row coname="client name 3" svcprovider="svc provider name 3" covalue="998" /> 
     <Row coname="client name 4" svcprovider="svc provider name 4" covalue="2081" /> 
     <Row coname="client name 5" svcprovider="svc provider name 5" covalue="3998" /> 
     <Row coname="client name 2" svcprovider="svc provider name 2" covalue="1081" /> 
     <Row coname="client name 1" svcprovider="svc provider name 1" covalue="998" /> 
     <Row coname="client name 2" svcprovider="svc provider name 2" covalue="1081" /> 
     <Row coname="client name 1" svcprovider="svc provider name 1" covalue="998" /> 
     <Row coname="client name 2" svcprovider="svc provider name 2" covalue="1081" /> 
    </Rows> 
</dsQueryResponse> 

結果是

<table> 
    <tr> 
     <th>Service Provider</th> 
     <th>Total Market value</th> 
     <th>No. Cos</th> 
     <th>Market value from top 100 cos</th> 
     <th>No. cos from top 100</th> 
    </tr> 
    <tr> 
     <td>svc provider name 2</td> 
     <td>4324</td> 
     <td>4</td> 
     <td>1081</td> 
     <td>4</td> 
    </tr> 
    <tr> 
     <td>svc provider name 1</td> 
     <td>2994</td> 
     <td>3</td> 
     <td>998</td> 
     <td>3</td> 
    </tr> 
    <tr> 
     <td>svc provider name 3</td> 
     <td>998</td> 
     <td>1</td> 
     <td>998</td> 
     <td>1</td> 
    </tr> 
    <tr> 
     <td>svc provider name 4</td> 
     <td>2081</td> 
     <td>1</td> 
     <td>0</td> 
     <td>0</td> 
    </tr> 
    <tr> 
     <td>svc provider name 5</td> 
     <td>3998</td> 
     <td>1</td> 
     <td>0</td> 
     <td>0</td> 
    </tr> 
</table> 
+0

我認爲這是幾乎正確的,因爲OP的解釋很難遵循。我認爲前100位的計算應該是在這裏所說的'totalvalue',它可以被減少到'sum(key('providerkey',@ svcprovider)/ @ covalue)''。除非客戶和供應商可以是相同的,否則我不會看到相關結果如何:供應商的總體結果,供應商前100名的供應商結果。其他可能性是前100名是在客戶**之間計算**。 – 2011-03-16 18:42:53

+0

@Alejandro:是的,問題沒有很好的定義,這個答案是我的猜測,但是無論如何,它都演示了在必要的完整問題定義可用時使用的技術。 – 2011-03-16 18:59:09

+0

我同意。這將需要一個部分結果樹作爲您的答案。 – 2011-03-16 19:15:07