将相似的元素分组到不同的组中

Grouping like elements into separate groups

我有以下 XML:

<root>
  <node>
    <prop>a</prop>
    <amount>10</amount>
  </node>
  <node>
    <prop>a</prop>
    <amount>20</amount>
  </node>
  <node>
    <prop>b</prop>
    <amount>15</amount>
  </node>
  <node>
    <prop>b</prop>
    <amount>25</amount>
  </node>
  <node>
    <prop>a</prop>
    <amount>17</amount>
  </node>
</root>

我想根据 prop:

将节点分组
<root>
  <segment>
    <prop>a</prop>
    <node>
      <amount>10</amount>
    </node>
    <node>
      <amount>20</amount>
    </node>
  </segment>
  <segment>
    <prop>b</prop>
    <node>
      <amount>15</amount>
    </node>
    <node>
      <amount>25</amount>
    </node>
  </segment>
  <segment>
    <prop>a</prop>
    <node>
      <amount>17</amount>
    </node>
  </segment>
</root>

但是如您所见,最后一个 "a" 节点必须放入另一个 segment - 这是因为三个 "a" 节点不连续。 当我尝试对它们进行分组时,所有 "a" 节点都放在一起。有没有办法按照示例中的指示对它们进行分组?

XSLT 1.0

中试试这个
    <?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
    <xsl:template match="node() | @*">
        <xsl:copy>
            <xsl:apply-templates select="node() | @*"/>
        </xsl:copy>
        </xsl:template>

    <xsl:output indent="yes"/>

    <xsl:template match="root">
        <xsl:copy>
            <xsl:for-each select="node[position() = 1 or prop != preceding-sibling::node[1]/prop]">
                <segment>
                    <xsl:copy-of select="prop"/>
                    <xsl:variable name="prop" select="prop"/>
                    <xsl:call-template name="retrivenode">
                        <xsl:with-param name="currentnode" select="."/>
                        <xsl:with-param name="prop" select="$prop"/>
                    </xsl:call-template>
                </segment>
            </xsl:for-each>
        </xsl:copy>
    </xsl:template>

    <xsl:template name="retrivenode">
        <xsl:param name="currentnode"/>
        <xsl:param name="prop"/>
        <xsl:apply-templates select="$currentnode"/>
        <xsl:if test="$currentnode/following-sibling::node[1][prop = $prop]">
            <xsl:call-template name="retrivenode">
                <xsl:with-param name="currentnode" select="$currentnode/following-sibling::node[1]"/>
                <xsl:with-param name="prop" select="$prop"/>
            </xsl:call-template>
        </xsl:if>
    </xsl:template>

    <xsl:template match="node">
        <xsl:copy>
            <xsl:apply-templates select="*[not(local-name() = 'prop')]">

            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

请参阅 https://xsltfiddle.liberty-development.net/3NSTbfk

处的转换