Created
February 23, 2017 15:00
-
-
Save jamescummings/66bb7ce82266f9067e630d57aa973960 to your computer and use it in GitHub Desktop.
An XSLT to group and subGroup <l> elements
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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 method="xml" indent="yes"/> | |
<!-- | |
Group input like: | |
<root> | |
<l xml:id="ms1-26"> | |
<q target="#ms1-q-4">4</q> | |
</l> | |
<l xml:id="ms1-27"> | |
<q target="#ms1-q-4">4</q> | |
</l> | |
<l xml:id="ms1-28"> | |
<q target="#ms1-q-4">4</q> | |
<q target="#ms1-q-4.1" type="sub">1</q> | |
</l> | |
<l xml:id="ms1-29"> | |
<q target="#ms1-q-4">4</q> | |
<q target="#ms1-q-4.1" type="sub">1</q> | |
</l> | |
<l xml:id="ms1-30"> | |
<q target="#ms1-q-4">4</q> | |
</l> | |
</root> | |
with subGrouping for <l> which have multiple <q> elements in them | |
-James Cummings 2017-02-22 | |
--> | |
<!-- Match root element --> | |
<xsl:template match="/root"> | |
<!-- copy this root element to the output --> | |
<xsl:copy> | |
<!-- select all the l elements inside it and group them by the thing they have | |
in common, in this case the 8th number of the id that their children q point to. | |
--> | |
<xsl:for-each-group select="l" group-by="q/@target/substring(., 8, 1)"> | |
<!-- wrap a group element around each group --> | |
<group> | |
<!-- for each item in the current group, create groups adjacent to the truth or | |
falsehood of the count of q child elements being greater than one --> | |
<xsl:for-each-group select="current-group()" group-adjacent="boolean(count(q) gt 1)"> | |
<!-- test whether the current-grouping-key() is true() (here using a shortcut | |
but could have tested it =true() or =false() explicitly if we'd wanted --> | |
<xsl:choose> | |
<xsl:when test="current-grouping-key()"> | |
<!-- In the case the current grouping key is true, that is there is more than one q | |
then wrap it in a subGroup element | |
--> | |
<subGroup> | |
<!-- for each item in this current group (of l elements where there are more | |
than one q) copy it to the output. --> | |
<xsl:for-each select="current-group()"> | |
<xsl:copy-of select="."/> | |
</xsl:for-each> | |
</subGroup> | |
</xsl:when> | |
<!-- otherwise, there is not more than one q element --> | |
<xsl:otherwise> | |
<!-- so for each of these just copy it to the output not being inside a subGroup --> | |
<xsl:for-each select="current-group()"> | |
<xsl:copy-of select="."/> | |
</xsl:for-each> | |
</xsl:otherwise> | |
</xsl:choose> | |
</xsl:for-each-group> | |
</group> | |
</xsl:for-each-group> | |
</xsl:copy> | |
</xsl:template> | |
</xsl:stylesheet> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment