2009-12-23 26 views
1

我有一個有趣的XSL場景由你們運行。到目前爲止,我的解決方案似乎效率低下(轉換時間明顯增加),所以我認爲我會把它放在那裏。XSL效率問題 - 需要解決方案

場景 從以下XML中我們需要獲取每個類別的最新新聞項目的ID。

該XML 在XML中,我有一個新聞項目列表,新聞類別列表和項目類別關係列表。項目列表和項目類別列表也可以按隨機順序(不按日期排序)。

<news> 

    <itemlist> 
     <item id="1"> 
      <attribute name="title">Great new products</attribute> 
      <attribute name="startdate">2009-06-13T00:00:00</attribute> 
     </item> 
     <item id="2"> 
      <attribute name="title">FTSE down</attribute> 
      <attribute name="startdate">2009-10-01T00:00:00</attribute> 
     </item> 
     <item id="3"> 
      <attribute name="title">SAAB go under</attribute> 
      <attribute name="startdate">2008-01-22T00:00:00</attribute> 
     </item> 
     <item id="4"> 
      <attribute name="title">M&amp;A on increase</attribute> 
      <attribute name="startdate">2010-05-11T00:00:00</attribute> 
     </item> 
    </itemlist> 

    <categorylist> 
     <category id="1"> 
      <name>Finance</name> 
     </category> 
     <category id="2"> 
      <name>Environment</name> 
     </category> 
     <category id="3"> 
      <name>Health</name> 
     </category> 
    </categorylist> 

    <itemcategorylist> 
     <itemcategory itemid="1" categoryid="2" /> 
     <itemcategory itemid="2" categoryid="3" /> 
     <itemcategory itemid="3" categoryid="1" /> 
     <itemcategory itemid="4" categoryid="1" /> 
     <itemcategory itemid="4" categoryid="2" /> 
     <itemcategory itemid="2" categoryid="2" /> 
    </itemcategorylist> 

</news> 

我已經試過 使用RTF

<xsl:template match="/"> 

     <!-- for each category --> 
     <xsl:for-each select="/news/categorylist/category"> 

      <xsl:variable name="categoryid" select="@id"/> 

      <!-- create RTF item list containing only items in that list ordered by startdate --> 
      <xsl:variable name="ordereditemlist"> 
       <xsl:for-each select="/news/itemlist/item"> 
        <xsl:sort select="attribute[@name='startdate']" order="descending" data-type="text"/> 
        <xsl:variable name="itemid" select="@id" /> 
        <xsl:if test="/news/itemcategorylist/itemcategory[@categoryid = $categoryid][@itemid=$itemid]"> 
         <xsl:copy-of select="."/> 
        </xsl:if> 
       </xsl:for-each> 
      </xsl:variable> 

      <!-- get the id of the first item in the list --> 
      <xsl:variable name="firstitemid" select="msxsl:node-set($ordereditemlist)/item[position()=1]/@id"/> 

     </xsl:for-each> 

    </xsl:template> 

會很感激你有什麼想法。

謝謝, 亞歷克斯

回答

5

這裏是我會怎麼做:由相關類別ID

<xsl:stylesheet 
    version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
> 
    <xsl:output encoding="utf-8" /> 

    <!-- this is (literally) the key to the solution -->  
    <xsl:key name="kItemByItemCategory" match="item" use=" 
    /news/itemcategorylist/itemcategory[@itemid = current()/@id]/@categoryid 
    " /> 

    <xsl:template match="/news"> 
    <latest> 
     <xsl:apply-templates select="categorylist/category" mode="latest" /> 
    </latest> 
    </xsl:template> 

    <xsl:template match="category" mode="latest"> 
    <xsl:variable name="self" select="." /> 
    <!-- sorted loop to get the latest news item --> 
    <xsl:for-each select="key('kItemByItemCategory', @id)"> 
     <xsl:sort select="attribute[@name='startdate']" order="descending" /> 
     <xsl:if test="position() = 1"> 
     <category name="{$self/name}"> 
      <xsl:apply-templates select="." /> 
     </category> 
     </xsl:if> 
    </xsl:for-each> 
    </xsl:template> 

    <xsl:template match="item"> 
    <!-- for the sake of the example, just copy the node --> 
    <xsl:copy-of select="." /> 
    </xsl:template> 

</xsl:stylesheet> 

<xsl:key>索引中的每個新聞項目。現在您有一種簡單的方法來檢索屬於某個類別的所有新聞內容。其餘的都很簡單。

輸出對我來說:

<latest> 
    <category name="Finance"> 
    <item id="4"> 
     <attribute name="title">M&amp;A on increase</attribute> 
     <attribute name="startdate">2010-05-11T00:00:00</attribute> 
    </item> 
    </category> 
    <category name="Environment"> 
    <item id="4"> 
     <attribute name="title">M&amp;A on increase</attribute> 
     <attribute name="startdate">2010-05-11T00:00:00</attribute> 
    </item> 
    </category> 
    <category name="Health"> 
    <item id="2"> 
     <attribute name="title">FTSE down</attribute> 
     <attribute name="startdate">2009-10-01T00:00:00</attribute> 
    </item> 
    </category> 
</latest> 
+0

您是先生,是天才。從5:00轉變到1:47! – Maleks 2009-12-23 14:38:29

1

Your're通過全項循環和按日期排序他們,你把他們大多由於遠離在正確的分類不是之前。

也許這樣的事情可能更適合你的情況:

<xsl:variable name="ordereditemlist"> 
    <xsl:for-each select="/news/itemcategorylist/itemcategory[@categoryid = $categoryid]"> 
     <xsl:variable name="itemid" select="@itemid"/> 

從那裏繼續收集只有你實際需要,然後排序並複製它們的新聞項目。