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
2
votes
1 answer

XSLT Group/merge childs (using key)

I am trying to understand how to deduce a solution using a code I already wrote. In order to simplify I will explain first what I want to do and what I got so far. Suppose I have an XML variable in XSLT containing few nodes with the same title…
user1942476
  • 435
  • 1
  • 5
  • 8
2
votes
3 answers

XSLT to find lowest price

i am beginner in XSLT and using to transform XML to XML. I require to get Prices tag which has lowest sum. Source XML:
Ankur Raiyani
  • 1,509
  • 5
  • 21
  • 49
2
votes
2 answers

XSLT 1.0 - Concatenate known child nodes, group by unknown parent

I want to transform 1580 1586 1582
gbentley
  • 35
  • 5
2
votes
3 answers

Output grouped list in 3 columns using XSLT

I want to output grouped results in 3 columns. I'm not using a table so I guess I mean 3 sections of results (see the HTML) side-by-side. I've grouped results according to the value of one of their nodes, and grouped under a heading which is the…
John Smith
  • 31
  • 7
2
votes
1 answer

XSLT grouping on multiple keys using Muenchian method

This is the input file. All these blocks are wrapped in a tag which is not appearing, dunno why? And all these blocks are wrapped in a top level element . 1 11/10
20090401
Manks
  • 35
  • 1
  • 6
2
votes
2 answers

XSLT Transformation based on predefined output string

I need xslt to transform, My Xml is as below OrderRef1 ERP
KRP
  • 131
  • 1
  • 3
  • 15
2
votes
2 answers

XSL - group based on element properties

How do i group the elements below using 'insref' and 'pref' I have tried using generate key id in xslt version 1. XML :
2
votes
2 answers

handling the child tags in XSLT when the order of occurance is not specified

I am working on XSLT transformations. I have a source file where I have sometag called tag. Consider my source xml to be like this. Some Name Some ID
Some Address
Some…
Patan
  • 17,073
  • 36
  • 124
  • 198
1
vote
2 answers

replace namespace uri using XSLT in SOAP message

i have an input soap message, trying to replace part of namespace uri with a different string. I am able to replace entire URI with a different URI, but not able to modify the existing URI. I need to look for 'OLDSTRING' and replace with…
sarma
  • 63
  • 1
  • 12
1
vote
2 answers

How do I make group-by ignore white-space in XSLT?

I have an xml file which I need to group-by using xsl:for-each-group. Everything works fine but the problem comes from when there is elements which have white space at the end of them (e.g. test and test) but I need these…
Peymankh
  • 1,976
  • 25
  • 30
1
vote
1 answer

Groups two xml files like a sql group-by

With the following file as input of xsltprocessor : mylibrary.xml : and this one that can be used : bookreference.xml :
Seb
  • 141
  • 2
  • 7
1
vote
2 answers

Grouping when using 2 different XML files as sources?

what i want to do is a typical grouping that can usualy be done using xsl:key, but it become more complicated as data to groups are in 2 differents files. How process ? Here is an example of what i want to do, can i request your help ? must be…
Seb
  • 141
  • 2
  • 7
1
vote
1 answer

Compare element values in a array and fetch the biggest value elements inside the Parent element

I am trying to create a XSLT in 1.0.PLease find below a sample xml. The requirement is to get the biggest value1 field from all 3 and display the tags inside them. Request XML:
Krishna
  • 13
  • 2
1
vote
1 answer

Problem with multiple groups while transforming XML using XSLT

I had a problem with grouping while transforming xml to xml using xslt version 1.0 @michael.hor257k has kindly provided the solution to fix it. Link below: Problem transforming XML groups with XSLT However, I still need some improvements in the…
Nicky
  • 15
  • 4
1
vote
1 answer

Need XSLT Splitter for each record

Please note that source xml fieldscome in sequence means one student's info then another student info. Can you help on the XSLT to break xml as one group node for each student My Input is Below