如何从节点组中不改变顺序?

时间:2012-03-08 22:27:06

标签: xml xslt grouping

假设我们有一些水果或衣服的物品:

<items>
    <orange/>
    <banana/>
    <apple/>
    <jacket/>
    <shirt/>
    <trousers/>
    <apple/>
    <banana/>
    <jacket/>
    <apple/>
    <banana/>
</items>

我希望他们按照以下方式分组而不改变项目的顺序:

<items>
    <fruits>
        <orange/>
        <banana/>
        <apple/>
    </fruits>
    <clothes>
        <jacket/>
        <shirt/>
        <trousers/>
    </clothes>
    <fruits>
        <apple/>
        <banana/>
    </fruits>
    <clothes>
        <jacket/>
    </clothes>
    <fruits>
        <apple/>
        <banana/>
    </fruits>
</items>

我是XSLT的初学者,在浏览了无数的例子后,我仍然无法知道如何使用XSLT实现这一目标。

1 个答案:

答案 0 :(得分:3)

在XSLT2中,任何类型的分组都比XSLT1更容易,所以我假设你没有说XSLT2

<xsl:stylesheet version="2.0" 
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:f="data:f"
        exclude-result-prefixes="f">

<xsl:output indent="yes"/>

<xsl:template match="items">
 <xsl:for-each-group select="*"
             group-adjacent="f:type(.)">
  <xsl:element name="{current-grouping-key()}">
   <xsl:copy-of select="current-group()"/>
  </xsl:element>
 </xsl:for-each-group>
</xsl:template>

<xsl:function name="f:type">
 <xsl:param name="n"/>
 <xsl:apply-templates mode="type" select="$n"/>
</xsl:function>

<xsl:template mode="type" match="orange|banana|apple">fruits</xsl:template>

<xsl:template mode="type" match="shirt|trousers|jacket">clothes</xsl:template>

<xsl:template mode="type" match="*">x</xsl:template>

</xsl:stylesheet>