RE: [xsl] Grouping in XSLT 2.0 with multiple grouping levels

Subject: RE: [xsl] Grouping in XSLT 2.0 with multiple grouping levels
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Tue, 1 Feb 2005 11:47:18 -0000
One way to do this in a generalized mechanism is to write a recursive
grouping template and have the actual grouping criteria table-driven. I've
done this before (several times) with value-based grouping, but not with
positional grouping:

<xsl:variable name="levels"
   as="xs:string*"
   select="'^41_UeberschrG1$', '^43_UeberschrG2$', '_NovAo.', '_Strich',
  '_Litera', '_Sublitera', '_Ziffer'"/>

<xsl:template name="group">
  <xsl:param name="level" as="xs:integer"/>
  <xsl:param name="population" as="node()*"/>
  <xsl:for-each-group select="$population"
     group-starting-with="*[matches(local-name(.), $levels[$level])]">
    <xsl:variable name="x" as="node()*">
     <xsl:choose>
      <xsl:when test="matches(local-name(.), $levels[$level])">
        <xsl:copy>
          <xsl:copy-of select="@*"/>
          <xsl:copy-of select="current-group() except ."/>
        </xsl:copy>
      </xsl:when>
      <xsl:otherwise>
          <xsl:copy-of select="current-group()"/>
      </xsl:otherwise>
     </xsl:choose>
    </xsl:variable>
    <xsl:choose>
      <xsl:when test="$level = count($levels)">
        <xsl:sequence select="$x"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:call-template name="group">
          <xsl:with-param name="level" select="$level + 1"/>
          <xsl:with-param name="population" select="$x"/>
        </
      </
    </
  </
</

Not tested, and I don't really know whether I've understood the problem
correctly, but perhaps it gives you some ideas as to what's achievable.

(In this case the table of grouping keys is represented by a sequence of
regular expressions. In another one I did, it was a sequence of XPath
expressions, evaluated using saxon:evaluate).

Michael Kay
http://www.saxonica.com/


> -----Original Message-----
> From: Huditsch Roman [mailto:Roman.Huditsch@xxxxxxxxxxxxx]
> Sent: 01 February 2005 11:09
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: AW: [xsl] Grouping in XSLT 2.0 with multiple grouping levels
>
> Ok, I'll try to explain the rules:
>
> * The following elements must start a new group:
> 41_UeberschrG1, 43_UeberschrG2, *_NovAo*, *_Strich*,
> *_Litera*, *_Sublitera*, *_Ziffer*
> 	(* is used as wildcard)
>
> 	Logical Structur: 41_UeberschrG1
> 				|_ 43_UeberschrG2
> 					|_ *_NovAo*
> 						|_ *_Ziffer*
> 							|_ *_Litera*
>
> |_ *_Sublitera*
>
> 	|_ *_Strich*
>
> * All elements before the first element to be grouped should
> stay as they are
> * Each grouping level is "optional". That means that there
> may appear an litera as child of
> NovAo,...
> * the elements 68_UnterschrL and 69_UnterschrM must not be
> included in any group
>
> There are other rules, but they are a little bit difficult to
> explain here. But I am sure that I
> can adapt any solutions to my needs.
> Thank you very much for your patience!
>
> wbr,
> Roman
> _______________________________________
>
> Roman Huditsch
> IT and Electronic Publishing
> LexisNexis ARD Orac
> Marxergasse 25
> 1030 Vienna
> Austria
> ph: +43-1-534 52-1514
> f: +43-1-534 52-140
> e-mail roman.huditsch@xxxxxxxxxxxxx
> www.lexisnexis.at
>
>
> > -----Urspr|ngliche Nachricht-----
> > Von: Michael Kay [mailto:mike@xxxxxxxxxxxx]
> > Gesendet: Dienstag, 1. Februar 2005 10:42
> > An: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> > Betreff: RE: [xsl] Grouping in XSLT 2.0 with multiple
> grouping levels
> >
> > It's not clear what rules you are applying here. The first
> > element that's treated differently from the others is
> > <42_UeberschrG1>, and you haven't explained why. Nor have you
> > explained why this element ends when you get to the
> > <68_UnterschrL> element.
> >
> > To tackle this, we need some kind of description of the rules
> > you are applying that determine when a sequence of
> > consecutive elements is dropped down a level (that is, when a
> > sequence of consecutive elements is considered to form a group.)
> >
> > Michael Kay
> > http://www.saxonica.com/
> >
> > > -----Original Message-----
> > > From: Huditsch Roman [mailto:Roman.Huditsch@xxxxxxxxxxxxx]
> > > Sent: 01 February 2005 08:24
> > > To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> > > Subject: [xsl] Grouping in XSLT 2.0 with multiple grouping levels
> > >
> > > Hi,
> > >
> > > Ok, I'll do my best in trying to explain my use case.
> > >
> > > I have to transform source files produced via the Upcast
> conversion
> > > tool into XML files valid to a given XML Schema.
> > > My input files have a flat and arbitrary structure.
> > >
> > > Here is a sample input file:
> > >
> > > <?xml version="1.0" encoding="ISO-8859-1"?> <document>
> > > 	<part style="page: pageStyle1;">
> > > 		<section level="1">
> > > 			<heading class="02_BDGesBlatt"
> > > level="1">bundesgesetzblatt</heading>
> > > 			<par class="03_RepOesterr">f|r die
> > republik vsterreich</par>
> > > 			<par class="04_AusgabeDaten">Jahrgang
> > > 2004 Ausgegeben am 30. Dezember 2004 Teil I</par>
> > > 			<par class="05_Kurztitel">180.
> > > Bundesgesetz: <inline style="color:
> > > #000000;">Abgabendnderungsgesetz 2004 - AbgDG 2004</inline>
> > > 			</par>
> > > 			<par class="05_Kurztitel">(NR: GP XXII
> > RV 686 AB 734 S. 89. BR:
> > > 7160 AB 7184 S. 717.)</par>
> > > 			<par class="05_Kurztitel">[CELEX-Nr.:
> > > 32003L0030, 32003L0096]</par>
> > > 			<par class="11_Titel" style="color:
> > > #000000; ">180. Bundesgesetz, mit dem das
> > Einkommensteuergesetz 1988,
> > > das Kvrperschaftsteuergesetz 1988, das
> Umgr|ndungssteuergesetz, das
> > > Umsatzsteuergesetz 1994, das Gesundheits- und
> > > Sozialbereich-Beihilfengesetz 1996, das Internationale
> > > Steuerverg|tungsgesetz, das Geb|hrengesetz 1957, das
> > > Konsulargeb|hrengesetz 1992, das Investmentfondsgesetz 1993, das
> > > EU-Quellensteuergesetz, das EG-Amtshilfegesetz, das
> > > Normverbrauchsabgabegesetz, das Mineralvlsteuergesetz 1995, das
> > > Kommunalsteuergesetz 1993, das Neugr|ndungs-Fvrderungsgesetz, die
> > > Bundesabgabenordnung, das
> > Abgabenverwaltungsorganisationsgesetz, das
> > > Zollrechts-Durchf|hrungsgesetz, das Finanzstrafgesetz, das
> > > Bewertungsgesetz 1955, das Erbschafts- und
> > Schenkungssteuergesetz 1955
> > > sowie das Bundesbahngesetz gedndert werden
> (Abgabendnderungsgesetz 
> > > 2004 - AbgDG 2004)</par>
> > > 			<par class="12_PromKl_EinlSatz">Der
> > Nationalrat hat
> > > beschlossen:</par>
> > > 			<par class="42_UeberschrG1-">Artikel I</par>
> > > 			<par class="43_UeberschrG2">Dnderung
> > des Einkommensteuergesetzes 
> > > 1988</par>
> > > 			<par class="12_PromKl_EinlSatz">Das
> > Einkommensteuergesetz 1988,
> > > BGBl. Nr. 400, zuletzt gedndert durch das Bundesgesetz
> BGBl. I Nr. 
> > > 57/2004, wird wie folgt gedndert:</par>
> > > 			<par class="21_NovAo1">1. In ' 3 Abs. 1
> > Z 17 wird folgender Satz
> > > angef|gt:</par>
> > > 			<par
> > > class="23_Satz_(nach_Novao)">"Gutscheine f|r Mahlzeiten
> > bleiben bis zu
> > > einem Wert von 4,40 Euro pro Arbeitstag steuerfrei, wenn die
> > > Gutscheine nur am Arbeitsplatz oder in einer nahe gelegenen
> > Gaststdtte
> > > zur dortigen Konsumation eingelvst werden. Kvnnen die
> > Gutscheine auch
> > > zur Bezahlung von Lebensmitteln verwendet werden, die
> nicht sofort
> > > konsumiert werden m|ssen, sind sie bis zu einem Betrag von
> > 1,10 Euro
> > > pro Arbeitstag steuerfrei."</par>
> > > 			<par class="14_Abs">In der Novelle 1839
> > wird der Inhalt nich
> > > gedndert.</par>
> > > 			<par class="22_NovAo2">2. In ' 4 Abs. 4
> > Z 5 tritt an die Stelle der
> > > Wortfolge <inline class="992_Normal">"der
> > > Finanzlandesdirektion"</inline> die Wortfolge <inline
> > > class="992_Normal">"des Finanzamtes Wien 1/23"</inline>.</par>
> > > 			<par class="21_NovAo1">3. ' 4 Abs. 4 Z
> > > 7 lautet:</par>
> > > 			<par
> > > class="52_Ziffer_e1">"7.Aufwendungen f|r Aus- und
> > > Fortbildungsma_nahmen im Zusammenhang mit der vom
> Steuerpflichtigen
> > > ausge|bten oder einer damit verwandten beruflichen Tdtigkeit und
> > > Aufwendungen f|r umfassende Umschulungsma_nahmen, die auf eine
> > > tatsdchliche Aus|bung eines anderen Berufes abzielen.
> > Aufwendungen f|r
> > > Ndchtigungen sind jedoch hvchstens im Ausma_ des den
> > > Bundesbediensteten zustehenden Ndchtigungsgeldes der
> > Hvchststufe bei
> > > Anwendung des ' 13 Abs. 7 der Reisegeb|hrenvorschrift zu
> > > ber|cksichtigen."</par>
> > > 			<par class="68_UnterschrL"
> > > xml:lang="en" style="word-break-inside: hyphenate; ">Fischer</par>
> > > 			<par class="68_UnterschrL"
> > > xml:lang="en" style="word-break-inside: hyphenate;
> ">Sch|ssel</par>
> > > 		</section>
> > > 	</part>
> > > </document>
> > >
> > >
> > > Ok, so far so good. Having such an input file, I need to
> > group various
> > > elements (with <xsl:for-each-group starting-with>).
> > >
> > > At the end I would like to get a file like:
> > >
> > > <document>
> > > 	<part style="page: pageStyle1;">
> > > 		<section level="1">
> > > 			<heading class="02_BDGesBlatt"
> > > level="1">bundesgesetzblatt</heading>
> > > 			<par class="03_RepOesterr">f|r die
> > republik vsterreich</par>
> > > 			<par class="04_AusgabeDaten">Jahrgang
> > > 2004 Ausgegeben am 30. Dezember 2004 Teil I</par>
> > > 			<par class="05_Kurztitel">180.
> > > Bundesgesetz: <inline style="color:
> > > #000000;">Abgabendnderungsgesetz 2004 - AbgDG 2004</inline>
> > > 			</par>
> > > 			<par class="05_Kurztitel">(NR: GP XXII
> > RV 686 AB 734 S. 89. BR:
> > > 7160 AB 7184 S. 717.)</par>
> > > 			<par class="05_Kurztitel">[CELEX-Nr.:
> > > 32003L0030, 32003L0096]</par>
> > > 			<par class="11_Titel" style="color:
> > > #000000; ">180. Bundesgesetz, mit dem das
> > Einkommensteuergesetz 1988,
> > > das Kvrperschaftsteuergesetz 1988, das
> Umgr|ndungssteuergesetz, das
> > > Umsatzsteuergesetz 1994, das Gesundheits- und
> > > Sozialbereich-Beihilfengesetz 1996, das Internationale
> > > Steuerverg|tungsgesetz, das Geb|hrengesetz 1957, das
> > > Konsulargeb|hrengesetz 1992, das Investmentfondsgesetz 1993, das
> > > EU-Quellensteuergesetz, das EG-Amtshilfegesetz, das
> > > Normverbrauchsabgabegesetz, das Mineralvlsteuergesetz 1995, das
> > > Kommunalsteuergesetz 1993, das Neugr|ndungs-Fvrderungsgesetz, die
> > > Bundesabgabenordnung, das
> > Abgabenverwaltungsorganisationsgesetz, das
> > > Zollrechts-Durchf|hrungsgesetz, das Finanzstrafgesetz, das
> > > Bewertungsgesetz 1955, das Erbschafts- und
> > Schenkungssteuergesetz 1955
> > > sowie das Bundesbahngesetz gedndert werden
> (Abgabendnderungsgesetz 
> > > 2004 - AbgDG 2004)</par>
> > > 			<par class="12_PromKl_EinlSatz">Der
> > Nationalrat hat
> > > beschlossen:</par>
> > >
> > > 			<42_UeberschrG1>
> > > 				<titel>Artikel I</titel>
> > > 				<43_UeberschrG2>
> > > 					<titel>Dnderung des
> > > Einkommensteuergesetzes 1988</titel>
> > > 					<par
> > > class="12_PromKl_EinlSatz">Das Einkommensteuergesetz 1988,
> > BGBl. Nr. 
> > > 400, zuletzt gedndert durch das Bundesgesetz BGBl.
> > > I Nr. 57/2004, wird wie folgt gedndert:</par>
> > > 					<NovAo>
> > > 						<absatz>1. In '
> > > 3 Abs. 1 Z 17 wird folgender Satz angef|gt:</absatz>
> > >
> > > <23_Satz_(nach_Novao)>"Gutscheine f|r Mahlzeiten bleiben
> > bis zu einem
> > > Wert von 4,40 Euro pro Arbeitstag steuerfrei, wenn die
> > Gutscheine nur
> > > am Arbeitsplatz oder in einer nahe gelegenen Gaststdtte zur
> > dortigen
> > > Konsumation eingelvst werden. Kvnnen die Gutscheine auch
> > zur Bezahlung
> > > von Lebensmitteln verwendet werden, die nicht sofort
> > konsumiert werden
> > > m|ssen, sind sie bis zu einem Betrag von 1,10 Euro pro Arbeitstag
> > > steuerfrei."</23_Satz_(nach_Novao)>
> > > 					</NovAo>
> > > 					<par class="14_Abs">In
> > > der Novelle 1839 wird der Inhalt nich gedndert.</par>
> > > 					<NovAo>
> > > 						<absatz>2. In '
> > > 4 Abs. 4 Z 5 tritt an die Stelle der Wortfolge <inline
> > > class="992_Normal">"der Finanzlandesdirektion"</inline> die
> > Wortfolge
> > > <inline class="992_Normal">"des Finanzamtes Wien
> > > 1/23"</inline>.</absatz>
> > > 					</NovAo>
> > > 					<NovAo>
> > > 						<absatz>3. ' 4
> > > Abs. 4 Z 7 lautet:</absatz>
> > >
> > > <52_Ziffer_e1>"7.Aufwendungen f|r Aus- und
> Fortbildungsma_nahmen im
> > > Zusammenhang mit der vom Steuerpflichtigen ausge|bten oder
> > einer damit
> > > verwandten beruflichen Tdtigkeit und Aufwendungen f|r umfassende
> > > Umschulungsma_nahmen, die auf eine tatsdchliche Aus|bung
> > eines anderen
> > > Berufes abzielen. Aufwendungen f|r Ndchtigungen sind jedoch
> > hvchstens
> > > im Ausma_ des den Bundesbediensteten zustehenden
> > Ndchtigungsgeldes der
> > > Hvchststufe bei Anwendung des ' 13 Abs. 7 der
> > Reisegeb|hrenvorschrift
> > > zu ber|cksichtigen."<52_Ziffer_e1>
> > > 					</NovAo>
> > > 				</43_UeberschrG2>
> > > 			</42_UeberschrG1>
> > > 			<par class="68_UnterschrL"
> > > xml:lang="en" style="word-break-inside: hyphenate; ">Fischer</par>
> > > 			<par class="68_UnterschrL"
> > > xml:lang="en" style="word-break-inside: hyphenate;
> ">Sch|ssel</par>
> > > 		</section>
> > > 	</part>
> > > </document>
> > >
> > >
> > >
> > > All elements in the source document containing "NovAo" should be
> > > treated identically.
> > > There are of course other elements which need to be
> > grouped, but for a
> > > better understanding I have put them out of the source file.
> > >
> > > I managed to come up with a working version, but I am sure
> > there are a
> > > lot of problems in it.
> > > I decided to split up the entire transformation in multiple
> > > stylesheets where each of them groups another element. I
> > thought that
> > > would be best because I can't rely on any element existing in my
> > > source document and some elements like "NovAo" need special care.
> > >
> > > How would you deal with such requirements?
> > > How should a stylesheet doing such transformations look like?
> > > I first tried to write a template for "section" and do
> the grouping
> > > there, but that didn't work out, since I don't want every child
> > > element to be grouped...
> > >
> > > Every help is very much appreciated!
> > >
> > > I first wanted to send you one of my stylesheets, but I am
> > doing other
> > > element conversions as well, so it wouldn't produce the simple
> > > structure shown above...
> > >
> > > wbr,
> > > Roman
> > >
> > > > -----Urspr|ngliche Nachricht-----
> > > > Von: Michael Kay [mailto:mike@xxxxxxxxxxxx]
> > > > Gesendet: Dienstag, 1. Februar 2005 01:08
> > > > An: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> > > > Betreff: RE: [xsl] from start tag A to end tag B
> > > >
> > > > > Is there any resource showing some sophisticated grouping
> > > solutions
> > > > > using XSLT 2.0?
> > > > > I just take a look at Michael's XSLT 2.0 reference, but I
> > > need some
> > > > > examples with a more complex and felxible structure...
> > > >
> > > > I think you need to post a problem and we'll see what we
> > can do to
> > > > provide a solution.
> > > >
> > > > I could write an essay on recursive grouping but it might be
> > > > addressing a problem that you haven't got...
> > > >
> > > > Michael Kay
> > > > http://www.saxonica.com/

Current Thread