XSL效率问题 - 需要解决方案

Mal*_*eks 1 xslt performance

我有一个有趣的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>
Run Code Online (Sandbox Code Playgroud)

我尝试过 使用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>
Run Code Online (Sandbox Code Playgroud)

真的很感激你的想法.

谢谢,亚历克斯

Tom*_*lak 5

我将如何做到这一点:

<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>
Run Code Online (Sandbox Code Playgroud)

<xsl:key>指标由相关类别ID每条新闻.现在,您可以通过一种简单的方法检索属于某个类别的所有新闻项.其余的都是直截了当的.

输出给我:

<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>
Run Code Online (Sandbox Code Playgroud)