Questions tagged [xslt-grouping]

Grouping mechanisms that are specific to XSLT. Should always be complemented with either the xslt-1.0, xslt-2.0 or xslt-3.0 tag to indicate the version used.

Grouping in XSLT 3

Grouping in XSLT 3, the current and latest version of XSLT since 2017, can be achieved primarily using the xsl:for-each-group instruction where you select the items to be grouped, the grouping population, with the select attribute and then have three different ways to group the population:

  1. the group-by attribute selecting a sequence of grouping keys by which the grouping population is to be grouped
  2. the group-adjacent attribute selecting a sequence of grouping keys by which adjacent items in the population are to be grouped
  3. the group-starting-with or group-ending-with attributes defining patterns to identify and start groups based on pattern matching of the initial (group-starting-with) or final (group-ending-with) member of a group

Access to the items of a currently processed group is given by the current-group() function, access to the current grouping key by the current-grouping-key() function.

The XSLT 3 specification gives at least one example for each grouping approach directly in the specification section https://www.w3.org/TR/xslt-30/#grouping-examples; below you find links to XSLT fiddles based on these examples:

Of course the different approaches can, for more complex tasks, be combined by nesting xsl:for-each-group instructions.

XSLT 3 with XPath 3.1 support can also group JSON represented as XPath 3.1 maps and arrays, here is a list of showing the previous XML grouping samples now using JSON input and directly grouping the map/array data structure returned by the parse-json function:

Positional grouping

Positional grouping can be used to split a sequence of items into groups of a certain size; in XSLT 2 or 3 this is easily achieved using e.g. for-each-group select="foo" group-adjacent="(position() - 1) idiv $chunk-size": https://xsltfiddle.liberty-development.net/asoTK9

https://martin-honnen.github.io/xslt/generic-positional-grouping-functions.xsl is a compact XSLT 3 module using higher-order functions importable by other code that needs to split up a sequence of items using positional grouping, you could use it as follows (Saxon-JS 2, Saxon 10 or higher all editions, Saxon 9.8 or higher PE and EE, Altova XML 2017 R3 or later)

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="3.0"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:mf="http://example.com/mf"
    xmlns:ex="http://example.com/ex"
    exclude-result-prefixes="#all"
    expand-text="yes">

  <xsl:import href="https://martin-honnen.github.io/xslt/generic-positional-grouping-functions.xsl"/>

  <xsl:function name="ex:wrap-rows" as="element()">
    <xsl:param name="group" as="item()*"/>
    <xsl:param name="pos" as="xs:integer"/>
    <xsl:param name="wrapper-name" as="xs:QName"/>
    <xsl:element name="{$wrapper-name}" namespace="{namespace-uri-from-QName($wrapper-name)}">
      <xsl:attribute name="index" select="$pos"/>
      <xsl:sequence select="$group"/>
    </xsl:element>
  </xsl:function>

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

  <xsl:template match="root">
    <root>
      <xsl:sequence select="mf:group-chunks(item, 3, ex:wrap-rows(?, ?, QName('', 'chunk')))"/>
    </root>
  </xsl:template>

  <xsl:template match="/">
    <xsl:next-match/>
    <xsl:comment>Run with {system-property('xsl:product-name')} {system-property('xsl:product-version')} {system-property('Q{http://saxon.sf.net/}platform')}</xsl:comment>
  </xsl:template>

</xsl:stylesheet>

to e.g. wrap any chunk into a container element.

Grouping in XSLT 2

Grouping in XSLT 2 also works with the xsl:for-each-group instruction as in XSLT 3, the main restrictions are that XSLT 2 does not support composite grouping keys (so to group on various items you need to concat or string-join them as single value (e.g. composite="yes" group-by="foo, bar" in XSLT 3 needs to be done as group-by="string-join((foo, bar), '|')")) and that pattern matching can only be done on nodes, not on primitive values.

The XSLT 2 specification gives at least one example for each grouping approach directly in the specification section https://www.w3.org/TR/xslt20/#grouping-examples; below you find links to XSLT fiddles based on these examples:

Grouping in XSLT 1.0

The preferred solution in XSLT 1.0 is to use the Muenchian grouping method:
http://www.jenitennison.com/xslt/grouping/muenchian.html

552 questions
-1
votes
1 answer

XSL transformation to add namespace and header (input & output described)

Beginner to XSL transformation, looking for help to convert the data using xsl. Input data is as below:
-1
votes
2 answers

Display unique values in xslt version 1

Can someone help me plz to get a distinct values of attribute ID in node INDIC ? Explication: Im using xslt version 1. This is how my xml looks like:
Sacamoto
  • 107
  • 1
  • 8
-1
votes
1 answer

Total of consecutively dated time offs of the same type in xslt

I have a requirement to print consequently dated time offs of the same type into a single row with total time off being sum of units of each time off row and a start date having the start date of the oldest time off row and the end date being the…
Arthi
  • 17
  • 3
-1
votes
3 answers

How to group consecutive dates in XSLT?

I have an xml file (sample below) and I want to group this xml based on consecutive Time_Off_Date. 101 2017-12-01
Ankita
  • 9
  • 4
-1
votes
1 answer

How to add custom tags in xslt?

can we add custom tag or function in XSLT.I will explain again I added one taginclude-html in my demo .can we add any logic in XSLT when we find include-html in my stylesheet it matches that template with tag value (same as we do in apply-template)…
naveen
  • 867
  • 4
  • 18
  • 42
-1
votes
1 answer

Merging text nodes in XSLT

I have been trying to merge all the text nodes in books.xml if their attribute values matches. And these values shoud be seperated by any delimeter(EX: , etc..) Here is the souce XML: Gambardella,…
-1
votes
1 answer

how to add condition in xslt?

I am trying to parse is xml 1 2
user5711656
  • 3,310
  • 4
  • 33
  • 70
-1
votes
1 answer

how to remove empty value in xslt?

I am using this algo http://www.jenitennison.com/xslt/grouping/muenchian.html for grouping . I am able to use that algo .but I am facing one issue .I have one xml in which i apply grouping on Over .I am able to show my data .but sometime @over…
user944513
  • 12,247
  • 49
  • 168
  • 318
-1
votes
1 answer

XSLT apply templates conditioning

I've an issue in apply templates , consider my xml will be like this , enter code here
Inside main all the step1 will be…
Abyy
  • 31
  • 1
  • 9
-1
votes
1 answer

XSLT for extracting elements from a non linear XML structure

I have a XML structure where the XML schema is irregular/not formatted. The structure looks like this- type0 Fruits .... Price0
QA Testing
  • 57
  • 7
-1
votes
3 answers

How to create html list from flat xml file using XSLT

I am looking for a clean way to do the following using XSLT. Convert this source: blah blah num1 num2 num3 blah blah num1 num2 blah blah blah blah…
joe
  • 16,988
  • 36
  • 94
  • 131
-1
votes
1 answer

Creating a CSV from XML using XSL

I am trying to extract customer data out of GNUCash XML file. The final goal is to get a comma-separated-value text file showing the customer data found within the XML data. The command I am using is xsltproc transform.xsl data.xml My xml input…
VQL
  • 1
  • 2
-1
votes
1 answer

Grouping Table elements in XML using XSLT

I have been working in the below conversion code for pretty long time. I am not sure the requirement is feasible in XSLT & need your help to identify whether its possible using XSLT. My input XML is as below,
Rajthilak
  • 13
  • 4
-1
votes
2 answers

Insert a parent node for a group of nodes in XSLT

I need to transform using XSLT an XML input:…
1 2 3
36
37