[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

Re: [xsl] nested groups from flat file


Subject: Re: [xsl] nested groups from flat file
From: "Imsieke, Gerrit, le-tex" <gerrit.imsieke@xxxxxxxxx>
Date: Tue, 08 Apr 2014 08:35:23 +0200

Use a named template or a function that you call recursively. Arguments are the items to be grouped (population) and the stack of names of elements that you want to group-starting-with:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output indent="yes"/>
<xsl:template match="doc">
<xsl:copy>
<xsl:call-template name="group">
<xsl:with-param name="population" select="*"/>
<xsl:with-param name="name-stack" select="('a', 'b', 'c', 'd')"/>
</xsl:call-template>
</xsl:copy>
</xsl:template>
<xsl:template name="group">
<xsl:param name="population" as="element(*)*"/>
<xsl:param name="name-stack" as="xs:string*"/>
<xsl:choose>
<xsl:when test="exists($population) and exists($name-stack)">
<xsl:for-each-group select="$population" group-starting-with="*[local-name() = $name-stack[1]]">
<xsl:element name="layer{$name-stack[1]}">
<xsl:copy-of select="."/>
<xsl:call-template name="group">
<xsl:with-param name="population" select="current-group() except ."/>
<xsl:with-param name="name-stack" select="$name-stack[position() gt 1]"/>
</xsl:call-template>
</xsl:element>
</xsl:for-each-group>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="$population"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>


On 08.04.2014 08:12, Szabo, Patrick (LNG-VIE) wrote:
Hi,

I'm using XSLT 2.0 and Saxon 9.3.
I have a flat markup and need to give it some structure.

Examplary markup

<a>...</a>
<b>...</b>
<c>...</c>
<d>...</d>
<e>...</e>
<d>...</d>
<d>...</d>

Desired result:

<layera>
       <a>...</a>
       <layerb>
              <b>...</b>
              <layerc>
                 <c>...</c>
                 <layerd>
                         <d>...</d>
                         <e>...</e>
                 </layerd>
                 <layerd>
                         <d>...</d>
                 </layerd>
                  <layerd>
                         <d>...</d>
                 </layerd>
         </layerc>
      </layerb>
</layera>

So I know where a new "layer" oft he strcture starts (it's a little more complicated but I simplified it to fit in an email) but I don't know how to wrap things like this.

I've tried nested groupings while always checking if there is a nother layer following but that seems very cumbersome and not elegant at all.

I've also tried matching the starts of layers and working with modes to wrap things but that get's very messy very quick and doesn't really work as intended either.

Is there a best practive to do this ? Maybe a feature of for-each-group that I'm unaware of ?

regards


. . . . . . . . . . . . . . . . . . . . . . . . . . Ing. Patrick Szabo Developer LexisNexis A-1030 Wien, Marxergasse 25

mailto:Patrick.Szabo@xxxxxxxxxxxxx
Tel.: +43 1 53452 1514
Fax.: +43 1 534 52 146

. . . . . . . . . . . . . . . . . . . . . . . . . .


-- Gerrit Imsieke GeschC$ftsfC<hrer / Managing Director le-tex publishing services GmbH Weissenfelser Str. 84, 04229 Leipzig, Germany Phone +49 341 355356 110, Fax +49 341 355356 510 gerrit.imsieke@xxxxxxxxx, http://www.le-tex.de

Registergericht / Commercial Register: Amtsgericht Leipzig
Registernummer / Registration Number: HRB 24930

GeschC$ftsfC<hrer: Gerrit Imsieke, Svea Jelonek,
Thomas Schmidt, Dr. Reinhard VC6ckler


Current Thread
Keywords