Re: [xsl] xsl-grouping two different elements together

Subject: Re: [xsl] xsl-grouping two different elements together
From: Martin Honnen <Martin.Honnen@xxxxxx>
Date: Tue, 16 Mar 2010 16:10:34 +0100
gregor FELLENZ wrote:

given the following structure:

<?xml version="1.0" encoding="UTF-8"?>
<kapitel>
    <abs>first</abs>
    <einschub1>first_ein</einschub1>
    <einschub1>second_ein</einschub1>
    <leerzeile/>
    <einschub1>third_ein</einschub1>
    <abs>second</abs>
    <einschub2>first_ein2</einschub2>
    <abs>end</abs>
</kapitel>

this should transform to:

<?xml version="1.0" encoding="UTF-8"?>
<kapitel>
    <abs>first</abs>
    <einschub typ="1">
        <abs>first_ein</abs>
        <abs>second_ein</abs>
        <leerzeile/>
        <abs>third_ein</abs>
    </einschub>
    <abs>second</abs>
    <einschub typ="2">
        <abs>first_ein2</abs>
    </einschub>
    <abs>end</abs>
</kapitel>

The following stylesheet achieves the output:


<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
  version="2.0">

<xsl:output method="xml" indent="yes"/>

<xsl:key name="k1" match="kapitel/leerzeile" use="generate-id(preceding-sibling::*[starts-with(local-name(), 'einschub')][1])"/>

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@*, node()"/>
    </xsl:copy>
  </xsl:template>

<xsl:template match="kapitel">
<xsl:copy>
<xsl:for-each-group select="* except leerzeile" group-adjacent="node-name(.)">
<xsl:choose>
<xsl:when test="starts-with(local-name-from-QName(current-grouping-key()), 'einschub')">
<einschub typ="{replace(local-name-from-QName(current-grouping-key()), '[^0-9]+', '')}">
<xsl:apply-templates select="current-group()"/>
</einschub>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>


  <xsl:template match="einschub1|einschub2">
    <abs>
      <xsl:apply-templates/>
    </abs>
    <xsl:apply-templates select="key('k1', generate-id())"/>
  </xsl:template>

</xsl:stylesheet>

but I am not sure it will work as you want with other possible input documents you might have.

Where all can "leerzeile" elements occur? What determines where they have to end up in the result?

--

	Martin Honnen
	http://msmvps.com/blogs/martin_honnen/

Current Thread