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】:

不需要任何&lt;xsl:for-each&gt; 指令来解决此问题(最好避免使用此指令):

<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>&#xA;</xsl:text>
     </z>
 </xsl:template>

 <xsl:template match="f[generate-id()=generate-id(key('kFByG',g)[1])]">
     <xsl:text>&#xA;</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 在每个目录中按标题分组

XSLT 1.0- 使用 Muenchian 方法创建表

我无法理解 XSLT 1.0 Muenchian 分组

XSLT muenchian 在子节点中按值分组

使用 XSLT muenchian-grouping 进行嵌套分组

xsl muenchian 分组多个级别