XSLT1,Muenchian 分组,在 foreach 循环中列出分组节点
Posted
技术标签:
【中文标题】XSLT1,Muenchian 分组,在 foreach 循环中列出分组节点【英文标题】:XSLT1, Muenchian grouping, listing the grouped nodes in a foreach loop 【发布时间】:2012-11-08 00:16:01 【问题描述】:给定xml代码
<z>
<f hit="1">
<g>hola1</g>
</f>
<f hit="2">
<g>hola2</g>
</f>
<f hit="3">
<g>hola1</g>
</f>
</z>
我想要xml输出
<z>
hola1
hola2
</z>
使用 xslt1。然后,一个简单的解决方案是 muenchian 分组
<xsl:key name="thisone" match="/z/f/g" use="." />
<z>
<xsl:for-each select="/z/f[generate-id(g)=generate-id(key('thisone',g)[1])]">
<xsl:value-of select="g" />
</xsl:for-each>
</z>
但是,当我将其应用于大型数据集时,系统 (firefox) 一直在思考。我认为这是由于数据集非常大。但是,“g”的不同值的数量确实很少。
我的问题是:有没有办法对 Muenchian 分组的节点进行 for-each 循环?类似的东西
<xsl:for-each select="nodes_of_key('thisone')">
这样可以避免比较所有“g”节点的所有值,这需要很长时间?
谢谢
【问题讨论】:
【参考方案1】:不需要任何<xsl:for-each>
指令来解决此问题(最好避免使用此指令):
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kFByG" match="f" use="g"/>
<xsl:template match="/*">
<z>
<xsl:apply-templates/>
<xsl:text>
</xsl:text>
</z>
</xsl:template>
<xsl:template match="f[generate-id()=generate-id(key('kFByG',g)[1])]">
<xsl:text>
</xsl:text>
<xsl:value-of select="g"/>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
当此转换应用于提供的 XML 文档时:
<z>
<f hit="1">
<g>hola1</g>
</f>
<f hit="2">
<g>hola2</g>
</f>
<f hit="3">
<g>hola1</g>
</f>
</z>
产生了想要的正确结果:
<z>
hola1
hola2
</z>
【讨论】:
是的,但使用相同的比较。我的问题是,当我有一个小文件要处理时,这是可行的,但是当这个文件较大时,浏览器会永远处理。因此,我的问题是,是否有任何方法可以避免比较所有节点,而只检查那些“存储”在 xsl:key 中的节点(如果可能的话) @Gerard,这是一个基于键的解决方案,它比比较一个值与所有其他值 (O(N^2)) 快几个数量级(接近 O(1))。 @Gerard,遍历“所有节点”是线性的——它非常快,甚至可能是 100 MB 大小的亚秒级。 但是,我该怎么办?我理解(我错了吗?)由于样式不推荐使用 foreach 指令(模板在 xslt 中更有意义),但如果它对效率没有任何影响(我错了吗?),那么基于键比较在一个包含 20.000 个条目的 7Mb 文件中永远进行(每个条目将成为一个要比较的节点)。我能做什么? @Gerard,这与是否使用xsl:for-each
无关。一个 7MB 的文件可以在几分之一秒内处理——这根本不是大文件。几百 MB 可以在 2-3 秒内处理。如果你的转型需要这么长时间,那么还有其他问题——不是 Muenchian 分组。这个问题可能根本与 XSLT 转换无关。我见过生成一个巨大表格的情况:转换需要不到一秒钟的时间,但浏览器需要永远格式化表格以进行显示。有一些我不记得的治疗方法(某种风格?)以上是关于XSLT1,Muenchian 分组,在 foreach 循环中列出分组节点的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Muenchian 分组 XSLT 1.0 在每个目录中按标题分组