我有一个有趣的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&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)
真的很感激你的想法.
谢谢,亚历克斯
我将如何做到这一点:
<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&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&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)