我是XSLT的新手,我想知道如何降低当前XSLT之一的速度..它目前正在获取一系列体育项目,以及一系列组,通过这些组循环,然后通过列表体育运动,看看它们是否匹配。
如果你有200个团体和50个体育项目,这是一个快速的10.000迭代..这必须更快。
我正在考虑编写一个新的查询来实现这样的结果:
<groups>
<group>
<id>12</id>
<sport>Football</sport>
</group>
<group>
<id>12</id>
<sport>Hockey</sport>
</group>
<group>
<id>12</id>
<sport>Swimming</sport>
</group>
<group>
<id>13</id>
<sport>Tennis</sport>
</group>
<group>
<id>13</id>
<sport>Basketball</sport>
</group>
</groups>
这样你只需要循环结果集,这样可以减少迭代次数。每次迭代都应检查下一次迭代是否具有相同的ID。是的,然后将这项运动作为一个参数传递到下一次迭代,如果是第二次迭代,它应该将它们传递到下一次。直到它到达下一次迭代不具有相同ID的点,这是应该将体育分组到单个对象的位置。
预期结果如下:
<groups>
<group>
<id>12</id>
<sport>Football</sport>
<sport>Swimming</sport>
<sport>Hockey</sport>
</group>
<group>
<id>13</id>
<sport>Tennis</sport>
<sport>Basketball</sport>
</group>
</groups>
我一直在尝试,但没有运气,这就是我现在的xslt的样子:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />
<xsl:template name="main" match="/">
<groups>
<xsl:for-each select="*/*/row">
<xsl:variable name="current" select="position()" />
<xsl:variable name="next" select="*/*/row[$current + 1]" />
<xsl:choose>
<xsl:when test="field[@name='GID'] = $next/field[@name='GIID']">
<xsl:variable name="sports" >
<sport><xsl:value-of select="field[@name='SPORT']" /></sport>
</xsl:variable>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="count($sports) > 0">
<xsl:call-template name="groups">
<xsl:with-param name="receivingSports" select="$sports" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="groups" />
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</groups>
</xsl:template>
<xsl:template name="groups">
<xsl:param name="receivingSports" />
<group>
<xsl:value-of select="$receivingSports"/>
<id>
<xsl:value-of select="field[@name='BIID']" />
</id>
</group>
</xsl:template>
</xsl:stylesheet>
答案 0 :(得分:1)
问题的解决方案是xsl:for-each-group
。 (我假设您使用的是XSLT 2.0;如果您处于仅限1.0的环境中,通常的建议是使用Muenchian分组(请参阅@JLRishe的回答)并考虑采取措施摆脱该环境。
答案 1 :(得分:0)
当你需要在XSLT 1.0中进行分组时,一个好的解决方案通常会使用Muenchian Grouping,就像在这里一样:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:key name="sports" match="group" use="id"/>
<xsl:template match="/*">
<xsl:copy>
<xsl:apply-templates select="group[generate-id() =
generate-id(key('sports', id)[1])]" />
</xsl:copy>
</xsl:template>
<xsl:template match="group">
<xsl:copy>
<xsl:copy-of select="id"/>
<xsl:copy-of select="key('sports', id)/sport" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
它不仅比使用count
快得多,而且更加简洁。
在样本输入上运行此操作时,结果为:
<groups>
<group>
<id>12</id>
<sport>Football</sport>
<sport>Hockey</sport>
<sport>Swimming</sport>
</group>
<group>
<id>13</id>
<sport>Tennis</sport>
<sport>Basketball</sport>
</group>
</groups>